阻塞在executorService的invokeAll方法中意味着什么?

时间:2019-05-09 17:18:47

标签: java multithreading concurrency executorservice

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

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

1 个答案:

答案 0 :(得分:-1)

请参见javadoc

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

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

是的,您是对的!参见下面的代码,这是AbstractExecutorService.java(oracle JDK8)中invokeAll的实现。更重要的是,您需要在此处注意到For循环。我们检查(!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);
    }
}