任务的拆分 fork,直到判断任务已经足够细粒度(原子任务),底层用到递归 类似微服务项目
由此我们可以看出对于ForkJoinPool来说一个大任务会细分多个子任务,每个子任务可以继续划分多个子任务直到不能划分为主,当各个阶段的任务都执行完此时会合并各个阶段返回的数据组成最终的返回值 相比于ThreadPoolExecutor来说 同一个任务ForkJoinPool可以被多个线程执行而ThreadPoolExecutor只能被一个线程执行.
每个线程执行的任务存在一个队列当中,当某一线程执行完自己的任务就会去窃取其他线程的任务,由于双向队列的原因每个线程的任务队列都是互通的在这里插入代码片
当我们使用callable或者是runnable 时任务窃取不会生效 此时只有实现ForkJoinTask类的子任务才会生效
10-100的计算
public class MyTest4 {
public static void main(String[] args) {
//不显示线程数量 默认是CPU核心数*2
ForkJoinPool forkJoinPool = new ForkJoinPool();
MyTask myTask = new MyTask(1,100 );
Integer invoke = forkJoinPool.invoke(myTask);
System.out.println(invoke);
forkJoinPool.shutdown();
}
}
class MyTask extends RecursiveTask<Integer> {
//两数之间间隔数
private int limit = 4;
//首
private int firstIndex;
//尾
private int lastIndex;
public MyTask(int firstIndex, int lastIndex) {
this.firstIndex = firstIndex;
this.lastIndex = lastIndex;
}
@Override
protected Integer compute() {
int result = 0;
int gap = lastIndex - firstIndex;
boolean flag = gap <= limit;
if (flag) {
System.out.println(Thread.currentThread().getName());
for (int i = firstIndex; i <= lastIndex; i++) {
result += i;
}
} else {//不符合要求对任务进行拆分
int middleIndex = (firstIndex + lastIndex) / 2;
MyTask leftTask = new MyTask(firstIndex, middleIndex);
MyTask rightTask = new MyTask(middleIndex + 1, lastIndex);
//执行递归操作 ForkJoinTask的静态方法 内部会执行我们重写的compute
// invokeAll(leftTask, rightTask);
// //同上
// invokeAll(leftTask);
// invokeAll(rightTask);
//同上
ArrayList<MyTask> objects = new ArrayList<>();
objects.add(rightTask);
objects.add(leftTask);
invokeAll(objects);
/*
join() 获取任务执行汇总结果
*/
int leftTaskResult = leftTask.join();
int rightTaskResult = rightTask.join();
result = leftTaskResult + rightTaskResult;
}
return result;
}
}
参看
参看
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- niushuan.com 版权所有 赣ICP备2024042780号-2
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务