ThreadPool(TP)和ForkJoinPool(FJ)针对不同的用例。主要区别在于不同执行者使用的队列数量决定了哪种类型的问题更适合任一执行者。
FJ执行程序具有n个(又是并行度级别)单独的并发队列(双端队列),而TP执行器只有一个并发队列(这些队列/双端队列可能是不遵循JDK Collections
API的自定义实现)。因此,在您生成大量(通常运行时间相对较短)任务的情况下,FJ执行程序的性能会更好,因为独立队列将最大程度地减少并发操作,而很少的窃取将有助于负载平衡。在TP中,由于只有一个队列,所以每次将工作出队时都会有并发操作,这将成为一个相对的瓶颈并限制性能。
相反,如果长期运行的任务相对较少,则TP中的单个队列不再是性能的瓶颈。但是,n个独立的队列和相对频繁的偷窃尝试现在将成为FJ的瓶颈,因为可能会有许多徒劳的偷窃尝试,这会增加开销。
此外,FJ中的工作窃取算法假设从双端队列中窃取的(较旧的)任务将产生足够的并行任务以减少窃取次数。例如,在快速排序或合并排序中,较旧的任务相当于更大的阵列,这些任务将生成更多任务,并使队列为非空,并减少总体窃取次数。如果在给定的应用程序中不是这种情况,那么频繁的窃取尝试将再次成为瓶颈。ForkJoinPool的javadoc中也指出了这一点:
此类提供状态检查方法(例如getStealCount()),旨在帮助开发,调整和监视fork / join应用程序。



