据说,当我们要等待所有任务的完成而不是提交或执行而不等待时,使用invokeAll。
完成任务是什么意思。这是否意味着产生所有其他线程的父线程会在该点卡住,直到所有线程返回为止?
答案 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);
}
}