我想Runnable
通过一种方法将任务提交到 ForkJoinPool:
forkJoinPool.submit(Runnable task)
注意,我使用 JDK 7。
在后台,它们被转换为 ForkJoinTask 对象。我知道 ForkJoinPool 在将任务递归地拆分为较小的任务时是有效的。
问题:
如果没有递归,工作窃取在 ForkJoinPool 中是否仍然有效?
在这种情况下值得吗?
更新 1: 任务很小并且可能不平衡。即使对于严格相等的任务,诸如上下文切换、线程调度、停放、页面未命中等之类的事情也会阻碍导致不平衡。
更新 2: Doug Lea 在并发 JSR-166 兴趣组中写道,给出了一个提示:
当所有任务都是异步的并提交到池而不是分叉时,这也大大提高了吞吐量,这成为构建参与者框架以及许多您可能使用 ThreadPoolExecutor 的普通服务的合理方式。
我认为,当涉及到相当小的 CPU 密集型任务时,ForkJoinPool 是要走的路,这要归功于这种优化。要点是这些任务已经很小,不需要递归分解。工作窃取工作,无论是大任务还是小任务 - 任务都可以被另一个空闲的工作人员从忙碌的工作人员的双端队列中抢走。
更新 3: ForkJoinPool 的可扩展性- Akka 乒乓球团队的基准测试显示了很好的结果。
尽管如此,要更有效地应用 ForkJoinPool 需要进行性能调整。