java - 为什么要在 invokeAll 方法之后调用 join 呢?

标签 java multithreading concurrency java.util.concurrent invokeall

我正在尝试了解 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 文档,invokeAll() 将任务提交到任务池并返回结果。因此不需要单独的 join()。有人可以解释为什么在这种情况下需要单独的连接吗?

最佳答案

在您的示例中,您使用的是 RecursiveTask<Integer> 所以你期望从 compute() 返回一个值方法。

让我们看看invokAll(t1,t12)签名。

static void invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2)

所以 invokeAll()没有返回值。 根据文档:

Forks the given tasks, returning when isDone holds for each task or an (unchecked) exception is encountered, in which case the exception is rethrown.

所以:

return subTask1.join() + subTask2.join();是你的例子的关键。 两个任务在每个任务完成后合并,将结果递归传递给下一次调用 compute()方法。

task.join()

Returns the result of the computation when it is done.

关于java - 为什么要在 invokeAll 方法之后调用 join 呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48634809/

相关文章:

java - ReentrantReadWriteLock(java)-在读取锁内嵌套写入锁

java - ForkJoinPool 与普通递归

与 CPU 核心数量相关的多线程和并行性

java - 自动查找使用次数的方法?

c++ - 装修调度系统

java - 以原子方式递增存储在 ConcurrentHashMap 中的计数器

multithreading - 在Windows Store App中生成线程会在UI线程中的任何定时等待调用中导致死锁

java - 如何为 Eclipse 创建自定义配置编辑器插件?

Java将 double 型转换为日期格式

javascript - 无法使用 js 更新事件的文本字段 - 未定义