ThreadPoolExecutor vs ForkJoinPool: stealing subtasks

 ̄綄美尐妖づ 提交于 2019-12-04 03:50:42
LoganMzz

In ForkJoinPool, there are two kinds of queues — the pool one which you basically used when submitting a task, and the thread specific one (i.e. one for each thread). From a ForkJoinTask you can invoke new tasks (generally a split of your problem).

These new tasks are not offered to the pool queue but to the thread specific one. Thus, they are taken/pulled in priority to the pool one, as if you have done all the job in the same task. Furthermore, the invoker task appears to be blocked for subtask completion.

In reality, the "blocked time" is spent to consume subtasks. It will be stupid to let other threads "to loaf around" while one of them is flooded by work. So, "work stealing" takes place.

To go beyond. To be efficient, "work stealing" takes/pulls task from the opposite bound. This greatly reduces contention over queue writing.

Always in efficiency, it's better to only split the problem in two subtasks and let the subtask split again and again. Even if you know the problem must be split directly in N parts. This is because "work stealing" requires concurrent writes to a shared resource, so limit its activation and contention!

If you have 3000 tasks in advance, and they are not going to spawn other tasks, the two will not behave substantially differently: with 10 threads, 10 tasks will be run at a time until they are all done.

ForkJoinPool is designed for the case where you have one or a few tasks to start with, but the tasks know how to split themselves up into subtasks. In this situation, ForkJoinPool is optimized to permit tasks to check on the availability of processing threads and split themselves up appropriately.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!