concurrent之ForkJoin初识笔记
程序员文章站
2022-05-04 21:39:36
...
需要先认识 RecursiveTask
RecursiveTask:递归任务
描述:有一个fork类来把大任务分割成子任务,有可能子任务还是很大,所以还需要不停的分割,直到分割出的子任务足够小。
Fork/Join框架要完成两件事情:
1.任务分割:首先Fork/Join框架需要把大的任务分割成足够小的子任务,如果子任务比较大的话还要对子任务进行继续分割
2.执行任务并合并结果:分割的子任务分别放到双端队列里,然后几个启动线程分别从双端队列里获取任务执
行。子任务执行完的结果都放在另外一个队列里,启动一个线程从队列里取数据,然后合并这些数据。
在Java的Fork/Join框架中,使用两个类完成上述操作
1.ForkJoinTask:我们要使用Fork/Join框架,首先需要创建一个ForkJoin任务。该类提供了在任务中执行
fork和join的机制。通常情况下我们不需要直接集成ForkJoinTask类,只需要继承它的子类,Fork/Join框架
提供了两个子类:
a.RecursiveAction:用于没有返回结果的任务
b.RecursiveTask:用于有返回结果的任务
2.ForkJoinPool:ForkJoinTask需要通过ForkJoinPool来执行
任务分割出的子任务会添加到当前工作线程所维护的双端队列中,进入队列的头部。当一个工作线程的队列里
暂时没有任务时,它会随机从其他工作线程的队列的尾部获取一个任务(工作窃取算法)。
代码栗子:
package com.geek.forkjoin;
import com.geek.threadandjuc.base.CountTask;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;
public class ForkJoin1 extends RecursiveTask<Integer> {
private static final int THREAD_HOLD = 2;
private int start;
private int end;
public ForkJoin1(int start, int end) {
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
int sum = 0;
//如果任务足够小就计算
boolean canCompute = (end - start) <= THREAD_HOLD;
if (canCompute) {
for (int i = start; i <= end; i++) {
sum += i;
}
} else {
int middle = (start + end) / 2;
ForkJoin1 left = new ForkJoin1(start, middle);
ForkJoin1 right = new ForkJoin1(middle + 1, end);
//执行子任务
left.fork();
right.fork();
//获取子任务结果
int lResult = left.join();
int rResult = right.join();
sum = lResult + rResult;
}
return sum;
}
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
ForkJoin1 task = new ForkJoin1(1, 4);
Future<Integer> result = pool.submit(task);
try {
System.out.println(result.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
拆分后合并,结果为10
参考:
https://blog.csdn.net/weixin_41404773/article/details/80733324
https://blog.csdn.net/lichuangcsdn/article/details/80866497
推荐阅读
-
前端笔记之Vue(一)初识SPA和Vue&webpack配置和vue安装&指令
-
前端笔记之ES678&Webpack&Babel(上)初识ES678&Babel&let和const&解构&语法
-
前端笔记之JavaScript面向对象(三)初识ES6&underscore.js&EChart.js&设计模式&贪吃蛇开发
-
前端笔记之Vue(四)UI组件库&Vuex&虚拟服务器初识
-
前端笔记之React(一)初识React&组件&JSX语法
-
前端笔记之微信小程序(一)初识微信小程序&WXSS与CSS|WXML与HTML的差异&像素和DPR
-
前端笔记之Vue(一)初识SPA和Vue&webpack配置和vue安装&指令
-
前端笔记之ES678&Webpack&Babel(上)初识ES678&Babel&let和const&解构&语法
-
前端笔记之Vue(四)UI组件库&Vuex&虚拟服务器初识
-
新手前端笔记之--初识html标签_html/css_WEB-ITnose