ForkJoin
在大数据量的情况下,并行执行任务,提高效率
把大任务拆分成小任务
package com.zhong.forkjoin;
import java.util.concurrent.RecursiveTask;
/** ForkJoin之三种计算0~10亿内和值方法
* ForkJoin 并行执行任务,提高效率,大数据量
*/
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;
}
//计算的方法
@Override
protected Long compute() {
if ( (end-start)<temp ){
Long sum = 0L;
for (Long i = start; i <= end ; i++) {
sum += i;
}
return sum;
} else {
//forkjoin 递归
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();
}
}
}
测试类
package com.zhong.forkjoin;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.LongStream;
public class Test {
public static void main(String[] args) throws ExecutionException, InterruptedException {
test1(); //7688
test2(); //8186
test3(); //139
}
/*
操作比较大的数的时候,注意溢出问题
JDK7新特性,数字之间可以用下划线分割
int money = 10_0000_0000;
*/
//普通人, 用this。来调
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 并行流
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= "+ sum +" 时间:" + (end-start));
}
}