分支/合并框架
分支/合并框架的目的是以 递归方式将可以并行的任务拆分成更小的任务,然后将每个子任务的结果合并起来生成整体结果。
它是ExecutorService
接口的一个实现,它把子任务分配给线程池(称为ForkJoinPool
)中的工作线程。
ForkJoinSumCalculator
java
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.stream.LongStream;
//继承RecursiveTask来创建可以用于分支/合并框架的任务
public class ForkJoinSumCalculator extends RecursiveTask<Long> {
// ---------------------------框架的属性---------------------------
public static final ForkJoinPool FORK_JOIN_POOL = new ForkJoinPool();
// ---------------------------业务的属性---------------------------
public static final long THRESHOLD = 10_000; //不再将任务分解为子任务的数组大小
private final long[] numbers;
private final int start;
private final int end;
//公共构造函数 用于 创建主任务
public ForkJoinSumCalculator(long[] numbers) {
this(numbers, 0, numbers.length);
}
//私有构造函数 用于 以递归方式为主任务创建子任务
private ForkJoinSumCalculator(long[] numbers, int start, int end) {
this.numbers = numbers;
this.start = start;
this.end = end;
}
// 调用主任务入口
public static long forkJoinSum(long n) {
long[] numbers = LongStream.rangeClosed(1, n).toArray();
ForkJoinTask<Long> task = new ForkJoinSumCalculator(numbers);
return FORK_JOIN_POOL.invoke(task);
}
// 感觉像主管给不同人派活,然后收集结果
@Override
protected Long compute() {
int length = end - start;
if (length <= THRESHOLD) {
//如果大小小于或等于阈值,顺序计算结果
return computeSequentially();
}
ForkJoinSumCalculator leftTask = new ForkJoinSumCalculator(numbers, start, start + length / 2); //为数组的前一半求和
leftTask.fork(); // 另起一个ForkJoinPool线程 异步执行 新创建的子任务
ForkJoinSumCalculator rightTask = new ForkJoinSumCalculator(numbers, start + length / 2, end); //为数组的后一半求和
Long rightResult = rightTask.compute(); // 当前线程继续执行后半部分任务
Long leftResult = leftTask.join(); // 等leftTask执行完毕
return leftResult + rightResult; // 收集2个子任务结果组合
}
// 最底层的串行计算
private long computeSequentially() {
long sum = 0;
for (int i = start; i < end; i++) {
sum += numbers[i];
}
return sum;
}
}
使用
java
ForkJoinSumCalculator.forkJoinSum(10_000_000L)
# 结果
50000005000000
-----------------------------------------------------------------------------读书笔记摘自 书名:Java 8实战 作者:[英] Raoul-Gabriel Urma [意] Mario Fusco [英] Alan M