ForkJoin并行执行任务!提高效率!大数据量!
任务的分割与合并主流程
ForkJoin特点:工作窃取
这里面维护的都是双端队列
测试代码:
//求和计算的任务
/*
* 如何使用forkjoin
* 1.forkjoinPool通过它来执行
* 2.计算任务 forkjoinPool.execute(ForkJoinTask task)
* 3.计算类要继承ForkJoinTask
*/
public class ForkJoinDemo extends RecursiveTask<Long> {
private Long start;//1
private Long end;//1990900000
//临界值
private long temp=10000;
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();
}
}
}
public class Test {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//test1();//4478
//test2();//7173
//test3();//184
}
//普通程序员
public static void test1() {
Long sum=0L;
long start = System.currentTimeMillis();
for (int i = 1; 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();
Long sum=LongStream.rangeClosed(0,10_0000_0000).parallel().reduce(0,Long::sum);
long end = System.currentTimeMillis();
System.out.println("sum=" + sum + "时间:" + (end - start));
}
}