Java ExecutorService.invokeAll(超时,时间单位)与Future.get(超时,时间单位)
我正在使用ExecutorService.invokeAll(可调用、超时、时间单位)方法 在提交给ExecutorService的每个可调用服务中,我都有一个未来。get() 即使executorService已超时,future.get()是否仍将在后台运行 我是否必须指定未来的超时。获取(timeout,TimeUnit)并抛出TimeoutException以确保未来终止?来自 执行给定的任务,当所有任务完成或超时过期时,返回保存其状态和结果的未来列表 所以1。所有可调用的Java ExecutorService.invokeAll(超时,时间单位)与Future.get(超时,时间单位),java,concurrency,java.util.concurrent,Java,Concurrency,Java.util.concurrent,我正在使用ExecutorService.invokeAll(可调用、超时、时间单位)方法 在提交给ExecutorService的每个可调用服务中,我都有一个未来。get() 即使executorService已超时,future.get()是否仍将在后台运行 我是否必须指定未来的超时。获取(timeout,TimeUnit)并抛出TimeoutException以确保未来终止?来自 执行给定的任务,当所有任务完成或超时过期时,返回保存其状态和结果的未来列表 所以1。所有可调用的s将提供所有结
s将提供所有结果,包括来自future.get()
内部调用的结果,以及2。一旦invokeAll返回(即在超时之前),所有期货都将终止。As声明:
返回后,尚未完成的任务将被取消
没有明确说明,但它使用了Future.cancel(true)
,即中断正在运行的任务。由于Future.get()
支持中断,这将通过抛出InterruptedException
使其完成。如果您的Callable
没有捕捉到它,也没有执行任何可能重置中断状态的操作,这意味着如果指定给invokeAll
的超时时间已过,则可调用项将在Future.get()
中停止等待
但是,invokeAll
只取消未来,因此发送中断信号,但不等待线程对其作出反应并完成可调用的代码的执行。因此,当invokeAll
由于超时而完成时,一些线程可能仍然在已经取消的任务上运行。但是,如果这些任务仅仅包含一个future::get
,那么这不应该是一个问题
但是,如果您只想等待现有的未来的列表的完成,那么您可以更高效地执行此操作。毕竟,您正在将每个Future
包装成一个调用Future.get的Callable
,该invokeAll
将包装成另一个Future
,每个Future可能阻塞一个工作线程,然后等待所有这些Future.get的完成。最后一步正是这项任务的内容,因此您可以不用前面的步骤来完成它,例如
public static void waitForAll(Collection<? extends Future<?>> futures,
long timeout, TimeUnit unit)
throws InterruptedException {
long nanos = unit.toNanos(timeout);
boolean done = false;
try {
final long deadline = System.nanoTime() + nanos;
final int size = futures.size();
for(Future<?> f: futures) {
if(!f.isDone()) {
if (nanos <= 0L) return;
try { f.get(nanos, TimeUnit.NANOSECONDS); }
catch(CancellationException | ExecutionException ignore) {}
catch(TimeoutException toe) { return; }
nanos = deadline - System.nanoTime();
}
}
done = true;
}
finally { if (!done) for(Future<?> f: futures) f.cancel(true); }
}
publicstaticvoidwaitforall(集合>未来),
长超时(时间单位)
抛出中断异常{
long nanos=单位toNanos(超时);
布尔完成=假;
试一试{
最终长截止日期=System.nanoTime()+nano;
final int size=futures.size();
for(未来f:未来){
如果(!f.isDone()){
如果(nanos)假设一些future.get()没有收到任何结果,并且执行器服务超时。所有这些future.get()会发生什么情况?它们还会存在吗?@user1142317则会触发invokeAll
的超时。