簡體   English   中英

為什么要在invokeAll方法之后調用join?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM