1.什么是ForkJoin?
orkJoin 在 JDK 1.7 , 并行执行任务!提高效率。大数据量!
大数据:Map Reduce (把大任务拆分为小任务)
2.ForkJoin特点
工作窃取,这个里面维护的都是双端队列
3.ForkJoin结构
4.简单代码实现:
首先贴出forkjoinTask中的RecursiveTask的实现类
import java.util.concurrent.RecursiveTask;
/**
* @program: juc
* @description
* @author: 不会编程的派大星
* @create: 2021-04-27 10:20
**/
public class ForkJoinDemo extends RecursiveTask<Long> {
private Long start;
private Long end;
private Long temp = 100000L;
public ForkJoinDemo(Long start, Long end) {
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
if((end - start) < temp){
Long sum = 0L;
for ( long i = start; i <= end; i++) {
sum = sum+i;
}
return sum;
}else{
Long middle = (start + end) / 2;
ForkJoinDemo task1 = new ForkJoinDemo(start, middle);
task1.fork();//拆分任务,把任务压进线程队列
ForkJoinDemo task2 = new ForkJoinDemo(middle+1,end);
task2.fork();
return task1.join()+task2.join();
}
}
}
再来看看test类:
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.LongStream;
/**
* @program: juc
* @description
* @author: 不会编程的派大星
* @create: 2021-04-27 10:19
**/
public class ForkJoinTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
test1();
test2();
test3();
}
// 普通程序员
public static void test1(){
Long sum = 0L;
long start = System.currentTimeMillis();
for (Long i = 1L; i <= 10_0000_0000; i++) {
sum += i;
}
long end = System.currentTimeMillis();
System.out.println("sum="+sum+" 时间:"+(end-start));
}
// 会使用ForkJoin
public static void test2() throws ExecutionException, InterruptedException {
long start = System.currentTimeMillis();
ForkJoinPool forkJoinPool = new ForkJoinPool();
ForkJoinTask<Long> 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 test3(){
long start = System.currentTimeMillis();
// Stream并行流 () (]
long sum = LongStream
.rangeClosed(0L, 10_0000_0000L) // 计算范围(,]
.parallel() // 并行计算
.reduce(0, Long::sum); // 输出结果
long end = System.currentTimeMillis();
System.out.println("sum="+"时间:"+(end-start));
}
}
执行结果:
可以看出:
stream并行流 < forkjoin < 普通循环暴力计算
这次的讨论就到这里,欢迎小伙伴们留言讨论!