[英]When should we call join() after ForkJoinTask.invokeAll()
[英]Why should we call join after invokeAll method?
我正在嘗試了解ForkJoinPool框架,並遇到以下示例:
public class ArrayCounter extends RecursiveTask<Integer> {
int[] array;
int threshold = 100_000;
int start;
int end;
public ArrayCounter(int[] array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
}
protected Integer compute() {
if (end - start < threshold) {
return computeDirectly();
} else {
int middle = (end + start) / 2;
ArrayCounter subTask1 = new ArrayCounter(array, start, middle);
ArrayCounter subTask2 = new ArrayCounter(array, middle, end);
invokeAll(subTask1, subTask2);
return subTask1.join() + subTask2.join();
}
}
protected Integer computeDirectly() {
Integer count = 0;
for (int i = start; i < end; i++) {
if (array[i] % 2 == 0) {
count++;
}
}
return count;
}
}
主要:
public class ForkJoinRecursiveTaskTest
{
static final int SIZE = 10_000_000;
static int[] array = randomArray();
public static void main(String[] args) {
ArrayCounter mainTask = new ArrayCounter(array, 0, SIZE);
ForkJoinPool pool = new ForkJoinPool();
Integer evenNumberCount = pool.invoke(mainTask);
System.out.println("Number of even numbers: " + evenNumberCount);
}
static int[] randomArray() {
int[] array = new int[SIZE];
Random random = new Random();
for (int i = 0; i < SIZE; i++) {
array[i] = random.nextInt(100);
}
return array;
}
}
根據Java Docs,invokeAll()會將任務提交到池中並返回結果。因此,不需要單獨的join()。 有人可以解釋為什么在這種情況下為什么需要單獨的聯接嗎?
按照javadoc, join
完成后返回計算結果 。 此方法與get()的不同之處在於,異常完成會導致RuntimeException或Error而不是ExecutionException,並且調用線程的中斷不會導致該方法通過拋出InterruptedException突然返回。
因此,完成任務后, join
可幫助您獲取計算值,然后將其添加在一起。
return subTask1.join() + subTask2.join();
在您的示例中,您使用的是RecursiveTask<Integer>
因此您希望從compute()
方法返回一個值。
讓我們看一下invokAll(t1,t12)
簽名。
static void invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2)
因此invokeAll()
沒有返回值。 根據文檔:
分派給定任務,返回isDone對每個任務保持的時間,或者遇到(未檢查的)異常,在這種情況下,異常將被重新拋出。
所以:
return subTask1.join() + subTask2.join();
是您的示例的關鍵。 每個任務完成后,兩個任務都將合並,然后將結果遞歸傳遞給下一個對compute()
方法的調用。
task.join()
完成后返回計算結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.