【问题标题】:What does blocking means in invokeAll method of executorService? [duplicate]executorService的invokeAll方法中的阻塞是什么意思? [复制]
【发布时间】:2019-05-09 17:18:46
【问题描述】:

据说invokeAll是在我们想要等待所有任务完成时使用的,而不是提交或执行不等待。

完成任务是什么意思。这是否意味着产生所有其他线程的父线程卡在该点,直到所有线程返回?

【问题讨论】:

  • 这意味着一旦任务完成(正常或异常)该方法返回。集合中的每个Callable 都是一个任务。使用哪些线程来执行任务取决于ExecutorService。一个典型的实现是一个将重用现有线程的线程池。有多少线程可用或提交任务时是否创建线程取决于线程池的配置方式。

标签: java multithreading concurrency executorservice


【解决方案1】:

javadoc

<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
                          throws InterruptedException 

这是否意味着产生所有其他线程的父线程卡在该点,直到所有线程返回?

是的,你是对的!请参见下面的代码,这是来自 AbstractExecutorService.java(oracle JDK8)的 invokeAll 的实现。更重要的是,您需要注意那里的 For 循环。我们检查 if (!f.isDone()) ,这意味着如果任务没有完成(完成)进入循环并调用 f.get(),这是阻塞调用。实际上,您的 invokeAll 调用者将被阻塞,直到所有任务都未完成。

public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
    throws InterruptedException {
    if (tasks == null)
        throw new NullPointerException();
    ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
    boolean done = false;
    try {
        for (Callable<T> t : tasks) {
            RunnableFuture<T> f = newTaskFor(t);
            futures.add(f);
            execute(f);
        }
        for (int i = 0, size = futures.size(); i < size; i++) {
            Future<T> f = futures.get(i);
            if (!f.isDone()) {
                try {
                  f.get();
                } catch (CancellationException ignore) {
                } catch (ExecutionException ignore) {
                }
            }
        }
        done = true;
        return futures;
    } finally {
        if (!done)
            for (int i = 0, size = futures.size(); i < size; i++)
                futures.get(i).cancel(true);
    }
}

【讨论】:

  • 查看代码是理解 Java SE 功能的糟糕方式。只要遵守方法的约定,实现就可以从一个 Java 版本更改(并且已经更改)到下一个版本。
  • invokeall 的 Javadoc 并没有明确说明这是阻塞调用,可能这就是提出问题的原因。添加代码以在解释时提供更多清晰度。而且我知道代码可以更改,这就是我提供 jdk 版本和代码的原因。
  • javadoc 对此非常清楚:“执行给定的任务,返回一个持有其状态和结果的 Futures 列表全部完成时。对于返回列表的每个元素,Future.isDone()true。”这两个句子中的每一个都暗示了阻塞行为。
  • 在我看来英文句子可以写得更好,像我这样的普通人在第一次阅读时无法理解。 Blocking 关键字应该已经存在,或者我们可以编写类似“执行给定任务,仅在所有任务完成时返回 Futures 列表”之类的内容。 Off course futures 有 isDone 来检查状态,不知道为什么我们需要在这里添加“Holing their status”
猜你喜欢
  • 1970-01-01
  • 2013-02-20
  • 2011-01-25
  • 1970-01-01
  • 2013-10-19
  • 2013-07-28
  • 1970-01-01
  • 2011-04-26
  • 2020-10-27
相关资源
最近更新 更多