前言
当需要执行大量的小任务的时候,我们需要将多个小任务进行拆分,类似 快速排序
的 分而治之
。
Fork
将一个大任务进行递归,不断的把它切割成符合条件的小任务,然后这些子任务分配到不同 CPU 核心上去分别计算,提高效率,Join
是 获取到小任务的计算结果,最后合并返回。
它充分利用了现在多核 CPU 的性能。
正文
Fork/Join
框架的核心类是ForkJoinPool
,它能够接收一个ForkJoinTask
,并得到计算结果。ForkJoinTask
有两个子类,RecursiveTask
(有返回值)和RecursiveAction
(无返回结果),我们自己定义任务时,只需选择这两个类继承即可。
RecursiveAction
1 | // 没有返回值的 fork / join 任务框架 |
RecursiveTask
1 | // 有返回值的 fork / join 任务框架 RecursiveTask<T> |
- 结果:
1
2
3
4
5
6ForkJoinPool-1-worker-1 result is :1225
ForkJoinPool-1-worker-0 result is :8725
ForkJoinPool-1-worker-3 result is :3725
ForkJoinPool-1-worker-2 result is :6225
Fork Join calculated the result is 19900,consume 50018ms
The correct result is 19900,consume 200053ms
总结
- 我们虽然可以通过调整阈值
THRESHOLD
控制子任务的大小,从而控制了任务的数量,但是我们分配的Fork/Join Pool
数量却是根据 CPU 性能而定的,所以,切割任务的大小和数量需要进行预先计算好,不是子任务越多就越好,而且合并结果集,需要消耗其他的计算性能。如果任务大小不能控制,可以设计可伸缩算法,动态来计算出合理的阈值,以符合要求。 - 注意正确的
Fork/Join
框架的写法,通过廖老师的文章 Java的Fork/Join任务,你写对了吗? ,指出了错误的写法的问题所在。