Fork/Join框架的基本使用

问题

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

解决方法

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

public class ArraySumTask extends RecursiveTask<Long> {
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 方法获取异常.

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容