在我们的工作中经常会面临不得不在代码里进行大量计算的情况,在面临大量计算的时候,我们可以使用ForkJoin的方式进行任务分解。
ForkJoin在JDK1.7中提出,可以并行执行任务,用于大数据量的计算。
他的原理就是将一整个大的任务分成多个子任务同时进行。
特点:工作窃取,使用双端队列,当有空闲的线程时,自动拿取工作线程未做的任务。
使用方法:
1.继承RecursiveTask类(有返回值),也可继承RecursiveAction类(无返回值)
package com.test.test; import java.util.concurrent.RecursiveTask; public class ForkJoinDemo extends RecursiveTask{ //用于进行任务拆分的方法 @Override protected Integer compute() { return null; } }
2.拆分任务
package com.test.test; import java.util.concurrent.RecursiveTask; public class ForkJoinDemo extends RecursiveTask{ private int start; private int end; private int limit = 100; public ForkJoinDemo(int start, int end) { this.start = start; this.end = end; } @Override protected Integer compute() { // 如果任务的计算量小于limit则不再分解任务(一定要有) if ((end - start) < limit) { int sum = 0; for (int i = start; i <= end; i++) { sum += i; } return sum; }else { // 取中间值 int middle = (start + end)/2; // 目的是进行任务分解,重新创建一个ForkJoinDemo类,并递归调用compute方法 ForkJoinDemo demo1 = new ForkJoinDemo(start, middle); // 将任务压进线程队列(双端队列) demo1.fork(); ForkJoinDemo demo2 = new ForkJoinDemo(middle + 1, end); demo2.fork(); // 等待任务全部结束后,返回最终值 return demo1.join() + demo2.join(); } } }
3.执行ForkJoin任务
package com.test.test;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
public class Class1 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ForkJoinPool forkJoinPool = new ForkJoinPool();
// 执行任务无返回值
forkJoinPool.execute(new ForkJoinDemo(1, 10000));
// 提交任务有返回值
ForkJoinTask submit = forkJoinPool.submit(new ForkJoinDemo(1, 10000));
// 阻塞程序,等待任务运行完成,返回任务值
// 需要抛出ExecutionException, InterruptedException
submit.get();
}
}
使用ForkJoin可以使计算加快,但是仅了解就好,因为在JDK1.8中,我们有了Stream流式计算,这种计算的效率可是几十倍的提升。
// rangeClosed是(]区间,range是()区间 // parallel开始并行 IntStream.rangeClosed(1, 10000).parallel().reduce(0, Integer::sum);
有需要更多Stream流计算的话可以看一下我下面的文章↓
Java8中Stream操作集合



