Java 的 Fork/Join 框架是一个并行执行框架,它旨在通过递归地将任务分解成更小的子任务,并在多核处理器上并行执行这些子任务来提高性能。Fork/Join 框架是 Java 7 中引入的,位于 java.util.concurrent
包中。其核心思想是将一个大任务分解成多个小任务,然后将这些小任务并行执行,最终合并结果。
以下是使用 Fork/Join 框架的步骤和示例:
1. Fork/Join 基本概念
- Fork:将任务分解为更小的子任务并将其分派给线程池。
- Join:合并子任务的结果。
2. 核心类
ForkJoinPool
:管理和调度任务的线程池。RecursiveTask<V>
:用于有返回结果的任务。RecursiveAction
:用于没有返回结果的任务。
3. 示例:使用 Fork/Join 框架计算数组的和
步骤 1:创建任务类
创建一个继承 RecursiveTask
的任务类,用于计算数组的和。
import java.util.concurrent.RecursiveTask;
public class SumTask extends RecursiveTask<Long> {
private static final int THRESHOLD = 1000; // 阈值
private int[] array;
private int start;
private int end;
public SumTask(int[] array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
if (end - start <= THRESHOLD) {
// 小任务,直接计算
long sum = 0;
for (int i = start; i < end; i++) {
sum += array[i];
}
return sum;
} else {
// 大任务,分解
int middle = (start + end) / 2;
SumTask leftTask = new SumTask(array, start, middle);
SumTask rightTask = new SumTask(array, middle, end);
// 执行子任务
leftTask.fork();
rightTask.fork();
// 合并结果
long leftResult = leftTask.join();
long rightResult = rightTask.join();
return leftResult + rightResult;
}
}
}
步骤 2:使用 ForkJoinPool 执行任务
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
public class ForkJoinDemo {
public static void main(String[] args) {
// 创建一个包含 10000 个整数的数组
int[] array = new int[10000];
for (int i = 0; i < array.length; i++) {
array[i] = i;
}
// 创建 ForkJoinPool
ForkJoinPool pool = new ForkJoinPool();
// 创建任务
ForkJoinTask<Long> task = new SumTask(array, 0, array.length);
// 提交任务并获取结果
long result = pool.invoke(task);
// 打印结果
System.out.println("Sum: " + result);
}
}
4. 分析
SumTask
类继承自RecursiveTask<Long>
,实现了compute
方法,该方法用于计算数组的和。如果任务的大小小于或等于阈值(THRESHOLD
),则直接计算,否则将任务分解成两个子任务并行执行。- 在
ForkJoinDemo
类中,创建了一个包含 10000 个整数的数组,并使用ForkJoinPool
执行SumTask
任务,最终打印出数组的和。
5. 处理没有返回值的任务
如果任务没有返回值,可以使用 RecursiveAction
类。以下是一个示例:
import java.util.concurrent.RecursiveAction;
public class PrintTask extends RecursiveAction {
private static final int THRESHOLD = 10;
private int start;
private int end;
public PrintTask(int start, int end) {
this.start = start;
this.end = end;
}
@Override
protected void compute() {
if (end - start <= THRESHOLD) {
for (int i = start; i < end; i++) {
System.out.println("Number: " + i);
}
} else {
int middle = (start + end) / 2;
PrintTask leftTask = new PrintTask(start, middle);
PrintTask rightTask = new PrintTask(middle, end);
leftTask.fork();
rightTask.fork();
leftTask.join();
rightTask.join();
}
}
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
PrintTask task = new PrintTask(0, 100);
pool.invoke(task);
}
}
总结
Java 的 Fork/Join 框架是一个强大的并行执行框架,适用于需要将任务分解为更小任务并行执行的场景。通过使用 ForkJoinPool
和递归任务(RecursiveTask
或 RecursiveAction
),可以显著提高多核处理器的性能利用率。