什么是fork join
JDK1.7开始
并行执行任务!提高效率 => 针对大数据量
大数据 => MapReduce (把把任务拆分成小任务)
ForkJoin 特点 : 工作窃取
已经执行完任务的线程会将尚未执行完的线程中的任务窃取过来,避免线程等待造成资源浪费 => 提高效率
这里维护的都是双端队列 Deque 【队列两端都可以存取】
ForkJoin测试
package com.liu.forkjoin;
import java.util.concurrent.RecursiveTask;
/**
* 求和计算的任务
* 3000=>for 6000 => forkjoin 9000 => Stream并行流
*/
public class ForkJoinDemo extends RecursiveTask<Long> {
private Long start;
private Long end;
private Long temp = 10000L;
public ForkJoinDemo(Long start,Long end) {
this.start = start;
this.end = end;
}
public static void main(String[] args) {
int sum = 0;
for (int i = 1; i <= 10_0000_0000; i++) {
sum += i;
}
System.out.println(sum);
}
@Override
protected Long compute() {
if ((end-start) < temp){ // 一般的求和
Long sum = 0L;
for (Long i = start; i <= end ; i++) {
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
package com.liu.forkjoin;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
// 测试类 求 0-10_0000_0000的和
public class Test {
//同一个任务 效率高几十倍!!
public static void main(String[] args) throws ExecutionException, InterruptedException {
// test1(); // 6303
// test2(); // 5846
test3(); // 150 ???
}
// 普通程序员
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));
}
// Stream并行流 调用API
public static void test3(){
Long start = System.currentTimeMillis();
// Stream并行流
// DoubleStream
// IntStream.rangeClosed()
Long sum = LongStream.rangeClosed(0L, 10_0000_0000L).parallel().reduce(0,Long::sum); // sum是一个求和函数 返回一个a+b的和
Long end = System.currentTimeMillis();
System.out.println("sum = " + sum + " 时间 :" + (end -start));
}
}
本质 :(RecursiveTask) 递归 返回一个ForkJoinTask