我们什么时候应该在 ForkJoinTask.invokeAll() 之后调用 join()

When should we call join() after ForkJoinTask.invokeAll()

API 说: “方法 invokeAll(在多个版本中可用)执行最常见的并行调用形式:分叉一组任务并将它们全部加入。”

所以我的假设是,如果我使用 invokeAll(),我就不再需要使用 fork()join() 方法。我也知道,一般来说,只有当任务 returns 一个值:RecursiveTask 的子类时才会调用 join() 并且如果任务不返回值则不使用:子类:RecursiveAction.

我遇到了这个教程,它在调用之后调用了 ForkJoinTask.join()invokeAll():

https://www.baeldung.com/java-fork-join

@Override
    protected Integer compute() {
        if (arr.length > THRESHOLD) {
            return ForkJoinTask.invokeAll(createSubtasks())
              .stream()
              .mapToInt(ForkJoinTask::join) // join() is called
              .sum();
        } else {
            return processing(arr);
        }
    }

还有这个post,在调用invokeAll()后使用了join():

invokeAll(subTask1, subTask2);

return subTask1.join() + subTask2.join();

与此同时,我查看了 invokeAll() 的许多其他示例,但在那个调用之后没有 join()

1) 在invokeAll()之后什么时候应该或什么时候不应该使用join()有什么规定吗?

2) invokeAll()有3种不同的签名,这个是根据方法的签名来决定是否使用join()吗?

3) 同样,我也在 API:

中阅读了这篇文章

"Method invoke() is semantically equivalent to fork(); join() but always attempts to begin execution in the current thread."

是说invoke()等于fork()加上join()吗?

  1. 当您需要计算结果时调用 join()。没有关于什么时候的规定。如果您有其他工作要做,您可以这样做,如果您没有其他工作要做并且需要计算结果,请调用 join()

  2. 签名反映了提供任务的不同方式。其中一个来自集合,另一个来自可变参数或数组,第三个提供两个作为参数。否则它们之间没有区别。使用最方便的那个。

  3. fork(); join() 是异步的,fork 的工作在另一个线程中,当前线程在调用 join 时等待工作完成。 invoke() 做同样的工作,但在当前线程中。