Fork/Join框架的基本使用

问题

假设有个非常大的long[]数组,通过FJ框架求解数组所有元素的和。

解决方法

任务类定义,因为需要返回结果,所以继承RecursiveTask,并覆写compute方法。任务的fork通过
ForkJoinTask的fork方法执行,join方法方法用于等待任务执行后返回:

public class ArraySumTask extends RecursiveTask {
private final int[] array;
private final int begin;
private final int end;
private static final int THRESHOLD = 100;
public ArraySumTask(int[] array, int begin, int end) {
this.array = array;
this.begin = begin;
this.end = end;
}
@Override
protected Long compute() {
long sum = 0;
if (end - begin + 1 < THRESHOLD) { // 小于阈值, 直接计算
for (int i = begin; i <= end; i++) {
sum += array[i];
}
} else {
int middle = (end + begin) / 2;
ArraySumTask subtask1 = new ArraySumTask(this.array, begin, middle);
ArraySumTask subtask2 = new ArraySumTask(this.array, middle + 1,
end);
subtask1.fork();
subtask2.fork();
long sum1 = subtask1.join();
long sum2 = subtask2.join();
sum = sum1 + sum2;
}
return sum;

调用方如下:

public class Main {
public static void main(String[] args) {
ForkJoinPool executor = new ForkJoinPool();
ArraySumTask task = new ArraySumTask(new int[10000], 0, 9999);
ForkJoinTask future = executor.submit(task);
// some time passed...
if (future.isCompletedAbnormally()) {
System.out.println(future.getException());
}
try {
System.out.println("result: " + future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}

注意:ForkJoinTask在执行的时候可能会抛出异常,但是没办法在主线程里直接捕获异常,所以
ForkJoinTask提供了isCompletedAbnormally() 方法来检查任务是否已经抛出异常或已经被取消了,
并且可以通过ForkJoinTask的getException 方法获取异常.

你可能感兴趣的:(Fork/Join框架的基本使用)