我希望通过一种方法将Runnable
任务提交到ForkJoinPool中:
forkJoinPool.submit(Runnable task)
注意,我使用的是JDK 7。
在底层,它们会被转换为ForkJoinTask对象。 我知道当任务递归地分成较小的任务时,ForkJoinPool非常高效。
问题:
如果没有递归,工作窃取是否仍然在ForkJoinPool中起作用?
在这种情况下是否值得使用?
更新1: 任务很小且可能不平衡。即使对于严格相等的任务,诸如上下文切换、线程调度、停车、页面错过等等也会导致不平衡。
更新2: Doug Lea在Concurrency JSR-166 Interest组中写道,提供了此提示:
当所有任务都是异步的并提交到池中而不是分叉时,这也极大地提高了吞吐量,这成为构建演员框架以及许多纯服务的合理方法,您否则可能会使用ThreadPoolExecutor。
我假设,在涉及相当小的CPU绑定任务时,ForkJoinPool是最佳选择,由于此优化,递归分解已经不再需要。 工作窃取会起作用,无论是大型还是小型任务-可以从忙碌工人的Deque尾部由另一个空闲工人抓取任务。
更新3: ForkJoinPool的可扩展性 - Akka团队对乒乓球进行基准测试并显示出色的结果。
尽管如此,要更有效地应用ForkJoinPool需要进行性能调整。