Java ExecutorService.invokeAll(超时,时间单位)与Future.get(超时,时间单位)

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将提供所有结

我正在使用ExecutorService.invokeAll(可调用、超时、时间单位)方法

在提交给ExecutorService的每个可调用服务中,我都有一个未来。get()

即使executorService已超时,future.get()是否仍将在后台运行

我是否必须指定未来的超时。获取(timeout,TimeUnit)并抛出TimeoutException以确保未来终止?

来自

执行给定的任务,当所有任务完成或超时过期时,返回保存其状态和结果的未来列表

所以1。所有可调用的
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
的超时。