思想:拆分归并
1.任务拆分 fork()
2.结果归并 join()
package learn.ForkJoin;
import java.util.concurrent.ForkJoinPool;
public class ForkJoinTest {
public static void main(String[] args) {
test();
}
public static void test(){
//统计时间
long l = System.currentTimeMillis();
//ForkPool
ForkJoinPool forkJoinPool = new ForkJoinPool();
ForkJoinWork task = new ForkJoinWork(0L, 1000000000L);//10亿
Long invoke = forkJoinPool.invoke(task);
long l2 = System.currentTimeMillis();
System.out.println("invoke="+invoke + "time:"+(l2-l));
}
}
package learn.ForkJoin;
import java.util.concurrent.RecursiveTask;
/**
* 定义一个任务
* */
public class ForkJoinWork extends RecursiveTask<Long> {
private Long start; //开始值
private Long end; //结束值
public final static Long critcal = 1000L;
public ForkJoinWork(Long start ,Long end) {
this.start = start;
this.end = end;
}
public ForkJoinWork(Long start ,Long end,long crital) {
this.start = start;
this.end = end;
}
//计算,如果不在临界值,进行拆分
/**
*
* 一般逻辑
*
* if(临界值){
* 计算
* }else{
* 继续拆分,直到临界值范围内
* }
* */
@Override
protected Long compute() {
//每次都会先拆分,拆分后判断是否满足临界点
long length = end - start;
if(length<critcal){
// 计算 start--end 的求和
Long sum = 0L;
for (Long i = start; i <=end; i++) {
sum += i;
}
return sum;
}else{
//拆分
//拆分任务
Long middle = (end+start)/2;
ForkJoinWork right = new ForkJoinWork(start, middle); //1. 第一条线
right.fork(); //分支
ForkJoinWork left = new ForkJoinWork(middle+1, end); //2. 第二条线
left.fork(); //分支
//合并
return right.join() + left.join();
}
}
}
和线程池差不多,我们先定义任务,然后扔到池子中,进行执行。
总结ForkJoinPool的三种task调用方式
execute(ForkJoinTask) 异步执行tasks,无返回值
invoke(ForkJoinTask) 有Join, tasks会被同步到主进程
submit(ForkJoinTask) 异步执行,且带Task返回值,可通过task.get 实现同步到主线程