Fork/Join框架
作用
并行计算的框架
在CPU密集行的任务中
一个大的任务往往可以拆分成很多个小的任务
这些小的任务处理完成后再组成一个大的结果
这个就是分治任务模型
也就是并行计算框架处理的任务模型
Fork(拆分)/Join(结合)
一般用作:
- 递归分解型任务
- 数组处理
- 并行化计算
- 大数据处理
使用步骤
- 构建一个任务的具体处理
编写拆分的逻辑
然后调用invokeAll
invokeAll会自动把任务提交和合并结果 - 构建ForkJoin池
和线程池的区别是,线程数就是CPU的逻辑核数
并且每个线程都持有一个队列
默认是先进后出的栈结构 - 调用ForkJoin池.invoke(具体任务)
设置自定义任务
这里的invokeAll就是把两个任务先fork 后 join
设置ForkJoin任务池
提交任务
任务拆分
这个例子中不涉及到任务合并如果有的话需要在 compute() 自己实现
实现具体的任务
接口是java.util.concurrent.ForkJoinTask
但是JDK以及提供了一些标准实现(抽象类)我们直接继承来用
比如递归处理RecursiveAction
Action是没有返回方法的
对应还有Task是有返回的
使用注意
- 使用的时候需要评估划分任务的深度,比如递归任务的时候需要关注递归的深度,避免栈溢出
- 最好自己指定专用的ThreadPoolExecutor来创建一个线程池
为啥快
- 每个工作线程都有自己的队列
- 线程窃取,空闲线程可以处理别的线程队列里的任务
ForkJoinWorkerThread
添加任务push()
出队任务pop()
窃取任务poll()