27、JUC:ForkJoin入门
作者:互联网
学习过程观看视频:[狂神说Java]
https://www.bilibili.com/video/BV1B7411L7tE?p=13
欢迎大家支持噢,很良心的老师了!
1、什么是ForkJoin?
2、ForkJoin 特点:工作窃取
这个里面维护的都是双端队列。
3、ForkJoin
java代码示例:
package com.function;
import jdk.nashorn.internal.ir.CallNode;
import java.util.concurrent.RecursiveTask;
/*** 求和计算的任务!
* 3000 6000(ForkJoin) 9000(Stream并行流)
* // 如何使用 forkjoin
* // 1、forkjoinPool 通过它来执行
* // 2、计算任务 forkjoinPool.execute(ForkJoinTask task)
* // 3. 计算类要继承 ForkJoinTask
*/
public class ForkJoinDemo extends RecursiveTask<Long> {
private Long start;
private Long end;
//临界值,使用ForkJoin进行求和计算
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.function;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.LongStream;
/**
* Created by zjl
* 2020/11/29
**/
public class ForkJoinDemoTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
test1();
}
//常规求和方式
public static void test1(){
Long sum = 0L;
Long startTime = System.currentTimeMillis();
for (int i = 0; i <= 10_0000_0000; i++) {
sum += i;
}
System.out.println(sum);
long endTime = System.currentTimeMillis();
System.out.println("运行时间" + (endTime/1000 - startTime/1000) + "秒");
}
//使用ForkJoin
public static void test2() throws ExecutionException, InterruptedException {
long startTime = System.currentTimeMillis();
ForkJoinPool forkJoinPool = new ForkJoinPool();
ForkJoinDemo forkJoinDemo = new ForkJoinDemo(0L, 10_0000_0000L);
ForkJoinTask<Long> submit = forkJoinPool.submit(forkJoinDemo); //提交任务
Long sum = submit.get();
System.out.println(sum);
long endTime = System.currentTimeMillis();
System.out.println("运行时间" + (endTime/1000 - startTime/1000) + "秒");
}
public static void test3(){
long startTime = System.currentTimeMillis();
// parallel()并行执行,Long::sum就是(l1,l2)->{return Long.sum(l1,l2)}
//reduce方法用于对stream中元素进行聚合求值,最常见的用法就是将stream中一连串的值合成为单个值,比如为一个包含一系列数值的数组求和
long sum = LongStream.rangeClosed(0L, 10_0000_0000L).parallel().reduce(0, Long::sum);
System.out.println(sum);
long endTime = System.currentTimeMillis();
System.out.println("运行时间" + (endTime/1000 - startTime/1000) + "秒");
}
}
运行结果分别为:
test1()方法:
test2()方法:
test3()方法:
注意:可能因为我电脑配置的原因,而数据量有不足够大,导致常规求和方式比使用ForkJoin要快。我们真正使用ForkJoin的时候,需要多次进行调试选出最优方案。
标签:JUC,27,sum,System,Long,start,ForkJoin,ForkJoinDemo 来源: https://blog.csdn.net/qq_41347385/article/details/110318022