概念
定义
JDK1.7之后,并行执行任务,提高效率。大数据量
将大任务分成几个小任务,用不同的线程去处理,最终合并结果
流程图
ForkJoin特点:工作窃取
里面维护的都是双端队列
代码
定义
/**
* 求和计算的任务!
* 如何使用 forkjoin
* 1. forkjoinPool 通过它来执行
* 2. 计算任务 forkjoinPool.execute(ForkJoinTask task)
* 3. 计算类继承RecursiveTask<返回类型>,重写compute方法
*/
public class ForkJoinDemo extends RecursiveTask<Long> {
private Long start;
private Long end;
//临界值,计算用
private Long temp = 10_000L;
public ForkJoinDemo(Long start, Long end) {
this.start = start;
this.end = end;
}
//计算方法
@Override
protected Long compute() {
if((end - start)<temp){
long sum = 0L;
for (int i = 0; i < end-start; i++) {
sum += i;
}
return sum;
}else {
//分支合并计算
//中间值
long middle = (start + end) / 2;
//分支,其实是递归写法,拆分成两个小的
ForkJoinDemo task1 = new ForkJoinDemo(start,middle);
task1.fork();
ForkJoinDemo task2 = new ForkJoinDemo(middle,end);
task2.fork();
return task1.join()+task2.join();
}
}
测试三种计算方法
/**
* @Author: XF-DD
* @Date: 20/05/26 16:33
*/
public class Test {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// test01(); //7696
// test02(); //421
test03();//255
}
public static void test01(){
Long sum = 0L;
long start = System.currentTimeMillis();
for(Long i = 0L; i<10_0000_0000; i++){
sum++;
}
long end = System.currentTimeMillis();
System.out.println("sum="+sum+" 时间:"+ (end-start));
}
public static void test02() throws ExecutionException, InterruptedException {
long start = System.currentTimeMillis();
ForkJoinPool forkJoinPool = new ForkJoinPool();
ForkJoinDemo task = new ForkJoinDemo(0L, 10_0000_0000L);
ForkJoinTask<Long> submit = forkJoinPool.submit(task);//提交任务
Long sum = submit.get();
long end = System.currentTimeMillis();
System.out.println("sum="+sum+" 时间:"+ (end-start));
}
public static void test03(){
long start = System.currentTimeMillis();
//Stream并行流() range:(];
long sum = LongStream.rangeClosed(0L, 10_0000_0000L)
.parallel() //并行计算
.reduce(0, Long::sum);
long end = System.currentTimeMillis();
System.out.println("sum="+sum+" 时间:"+ (end-start));
}
}