問題
假設(shè)有個(gè)非常大的long[]數(shù)組,通過FJ框架求解數(shù)組所有元素的和。
解決方法
任務(wù)類定義,因?yàn)樾枰祷亟Y(jié)果,所以繼承RecursiveTask,并覆寫compute方法。任務(wù)的fork通過
ForkJoinTask的fork方法執(zhí)行,join方法方法用于等待任務(wù)執(zhí)行后返回:
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) { // 小于閾值, 直接計(jì)算
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;
調(diào)用方如下:
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在執(zhí)行的時(shí)候可能會(huì)拋出異常,但是沒辦法在主線程里直接捕獲異常,所以
ForkJoinTask提供了isCompletedAbnormally() 方法來檢查任務(wù)是否已經(jīng)拋出異常或已經(jīng)被取消了,
并且可以通過ForkJoinTask的getException 方法獲取異常.