1.JAVA多线程(十七)Java多线程之ForkJoin框架
1.1 什么是ForkJoin框架?
Fork/Join 框架,可以将一个大的任务拆分成多个子任务进行并行处理,最后将子任务结果合并成最后的计算结果,并进行输出。通过这种方式,Fork/Join 能试着去使用所有可用的处理器,以达到加速处理多线程的目的。本文中对Fork/Join框架的讲解,基于JDK1.8+中的Fork/Join框架实现。
Fork/Join框架要完成两件事情:
-
任务分割:
首先Fork/Join框架需要把大的任务分割成足够小的子任务,如果子任务比较大的话还要对子任务进行继续分割。 -
执行任务并合并结果:
分割的子任务分别放到双端队列里,然后几个启动线程分别从双端队列里获取任务执行。子任务执行完的结果都放在另外一个队列里,启动一个线程从队列里取数据,然后合并这些数据。 -
ForkJoinTask类:
使用Fork/Join框架,首先需要创建一个ForkJoin任务。该类提供了在任务中执行fork和join的机制。通常情况下我们不需要直接集成ForkJoinTask类,只需要继承它的子类,Fork/Join框架提供了两个子类:
RecursiveTask: 用于有返回结果的任务
RecursiveAction:用于没有返回结果的任务
1.2 RecursiveTask使用样例
使用CalculatorRecursiveTask extends RecursiveTask完成1到10000累加的需求,代码如下:
package com.yuanxw.chapter17;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.stream.IntStream;
/**
* 使用CalculatorRecursiveTask extends RecursiveTask完成1到10000累加的需求
*/
public class ForkJoinRecursiveTask {
// 阈值
private final static int THRESHOLD = 200;
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 计算1-50累加值
CalculatorRecursiveTask calculatorRecursiveTask = new CalculatorRecursiveTask(1,10000);
ForkJoinPool forkJoinPool = new ForkJoinPool();
ForkJoinTask<Integer> forkJoinTask = forkJoinPool.submit(calculatorRecursiveTask);
System.out.println("计算结果:"+forkJoinTask.get());
}
/**
* 有返回值ForkJoin任务
*/
private static class CalculatorRecursiveTask extends RecursiveTask<Integer> {
// 开始计算机位置
public int first;
// 结束计算机位置