推荐答案
// www.javascriptcn.com code example
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
public class ForkJoinExample extends RecursiveTask<Long> {
private static final long THRESHOLD = 10000;
private final long[] numbers;
private final int start;
private final int end;
public ForkJoinExample(long[] numbers, int start, int end) {
this.numbers = numbers;
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
int length = end - start;
if (length <= THRESHOLD) {
return computeSequentially();
}
ForkJoinExample leftTask = new ForkJoinExample(numbers, start, start + length / 2);
leftTask.fork();
ForkJoinExample rightTask = new ForkJoinExample(numbers, start + length / 2, end);
Long rightResult = rightTask.compute();
Long leftResult = leftTask.join();
return leftResult + rightResult;
}
private long computeSequentially() {
long sum = 0;
for (int i = start; i < end; i++) {
sum += numbers[i];
}
return sum;
}
public static void main(String[] args) {
long[] numbers = new long[1000000];
for (int i = 0; i < numbers.length; i++) {
numbers[i] = i + 1;
}
ForkJoinPool pool = new ForkJoinPool();
ForkJoinExample task = new ForkJoinExample(numbers, 0, numbers.length);
long result = pool.invoke(task);
System.out.println("Sum: " + result);
}
}本题详细解读
1. Fork/Join 框架简介
Fork/Join 框架是 Java 7 引入的一个并行计算框架,主要用于将一个大任务拆分成多个小任务并行执行,最后将结果合并。它特别适用于递归分治算法的并行化。
2. 核心类
- ForkJoinPool: 用于管理并行任务的线程池。
- RecursiveTask: 用于有返回值的任务。
- RecursiveAction: 用于没有返回值的任务。
3. 代码解析
- ForkJoinExample 类: 继承自
RecursiveTask<Long>,表示一个有返回值的并行任务。 - compute() 方法: 这是任务的核心方法,判断任务是否足够小,如果足够小则直接计算,否则将任务拆分为两个子任务并行执行。
- computeSequentially() 方法: 用于顺序计算任务的结果。
- main() 方法: 创建一个大数组,初始化数据,并使用
ForkJoinPool来执行并行任务。
4. 关键点
- 任务拆分: 通过
fork()方法将任务拆分为子任务并异步执行。 - 结果合并: 通过
join()方法等待子任务完成并获取结果。 - 阈值控制: 通过
THRESHOLD控制任务拆分的粒度,避免任务过小导致性能下降。
5. 适用场景
Fork/Join 框架适用于可以递归拆分的任务,如数组求和、排序、矩阵乘法等。