目录
什么是ForkJoin
ForkJoin出现在JDK1.7,它的作用简单来说就是并行执行任务,通过把大任务拆分为小任务的思想,在计算大数量时,提高效率
ForkJoin的工作窃取机制
ForkJoin的执行核心是递归,ForkJoin把一个大任务拆分成多个小任务,并行执行。假设子任务A执行一半时,子任务B已经执行完毕了,B会窃取一些A的任务,来帮助A执行未完成的任务。而给A窃取B提供保证的就是双端队列,每个子任务都是个双端队列
并行流与ForkJoin的区别
并行流基于ForkJoin原理实现,它也是把大任务拆分成小任务执行,需要主要的是,并行流把每个任务拆分的足够小,然后让多个小任务同时执行,我们称之为并行,但单纯使用ForkJoin并不一样是并行执行的任务
高效率的求和方法:ForkJoin与并行流
我们用累加、ForkJoin、并行流三种方式求和。看看哪个效率最高
注意,使用ForkJoin需要自定义一个Forkjoin方法,让这个方法继承递归事件或递归任务类,然后设置划分子任务的条件,再进行提交子任务。
public class Test {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//test1(); //13232ms
//test2(); //12076ms
test3(); //595ms
}
//普通程序员
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();
long sum = LongStream.rangeClosed(0L, 10_0000_0000L).parallel().reduce(0, Long::sum);
long end = System.currentTimeMillis();
System.out.println("sum="+"时间: "+(end-start));
}
}
累加计算效率最高的是并行流~