2015-10-15 39 views
6

ForkJoinPoolForkJoinTask中,当前工作线程是否参与工作窃取?当前员工是否参与偷工作?

我已阅读的意义,一个叉连接池可以从工作阻塞或等待的线程窃取。目前的工人似乎是一个明显的人选。一旦工人在另一个任务上调用.join(),那么该任务基本上被阻止。

另一方面,我看到许多文章暗示不同的结论。例如,目前的工作线程应该在等待分支任务之前工作的普遍共识。

有迹象表明,讨论如何利用ForkJoinTask.getSurplusQueuedTaskCount由具有当前工人平衡在队列中的工作方法的几篇文章做一些工作。如果当前的工作人员也在偷窃,那么这似乎不是必要的。

当然,我想最大化线程操作并保持所有工作最大限度地运行。了解当前线程是否也在偷窃工作(例如,当调用.join时)将有助于澄清。

+0

你需要一个特定类型的问题,它是最大看到http://stackoverflow.com/questions/7926864/ fork-join-framework-better-a-thread-pool –

+1

我写了其中一篇文章,我可以保证你的join()不会导致窃取工作http:// coopsoft .com/ar/Calamity2Article.html#join工作窃取仅在deque为空时有效。就个人而言,我不会用getSurplus来微观管理框架....等等。 – edharned

回答

2

这是ForkJoinPool管理线程的责任。客户端代码应该为它提供任务,而不是微操作线程。请注意,任务和线程是两件不同的事情;任务是要执行的工作单元,并且线程执行该工作。如果任务的大小足以从并行运行任务的部分中受益,并且只要任务足够小以至于能够更好地运行,那么只需处理任务,ForkJoinTask.compute()应该将fork()分成更小的子任务在一个单一的线程。如果工作结果超出预期,它可以fork()一些工作,并完成其余的工作。

如果ForkJoinTask.compute()分叉成更小的子任务,它可以调用join()方法返回之前。然后,ForkJoinPool将释放该线程以处理其他任务,或者派生一个临时线程来处理其他任务,以确保可用并行性得到充分利用。

我认为这是合理的假设,工作线程的适当数量始终处于忙碌状态,只要有未完成任务的,除非你明确禁止在计算()方法的线程。

太阳教程提供了有关如何使用这些类更多的细节:

https://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html