作用:将大任务分解为小任务,然后把每个小任务的结果汇总,得到的是大任务的结果
什么是工作窃取算法
如何使用Fork/Join
- 创建任务:通过ForkJoinTask的两个子类定义任务。
- RecursiveAction:用于没有返回结果的任务
- RecursiveTask:用于有结果的任务
-
实例
需求:1+2+…+10000 ```java public class CountTask extends RecursiveTask
{ private static final int THRESHOLD = 2;
private int start; private int end;
public CountTask(int start, int end) {
this.start = start;
this.end = end;
}
@Override protected Integer compute() {
int sum = 0;
boolean canCompute = (end - start) <= THRESHOLD;
if (canCompute) {
for (int i = start; i <= end; i++) {
sum += i;
}
} else {
int middle = (start + end) / 2;
CountTask left = new CountTask(start, middle);
CountTask right = new CountTask(middle + 1, end);
left.fork();
right.fork();
int leftR = left.join();
int rightR = right.join();
sum = leftR + rightR;
}
return sum;
} }
========================
public static void main(String[] args) throws ExecutionException, InterruptedException {
ForkJoinPool forkJoinPool = new ForkJoinPool();
CountTask countTask = new CountTask(1, 100);
ForkJoinTask
Fork/Join框架异常处理
ForkJoinTask提供了isCompletedAbnormally()方法检查任务是否抛出异常或已经被取消了。
可以通过 ForkJoinTask.getException()来获取异常
- 返回Throwable对象
- 被取消返回 CancellationException
- 没有异常或没有完成,则为null
实现原理
ForkJoinPool的组成
ForkJoinTask的fork方法实现原理
pushTask()
将当前任务放在ForkJoinTask数组中,然后会创建一个工作线程去执行ForkJoinTask
ForkJoinTask的join方法实现原理
- 首先调用了doJoin,返回任务执行状态
- NORMAL:已完成
- CANCELLED:被取消
- SIGNAL:信号
- EXCEPTIONAL:出现异常
- doJoin()方法代码
- 若任务执行完成直接返回任务状态
- 若没有执行完,从数组中取出执行
- 成功:返回完成状态
- 异常:返回异常状态