首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ExecutorService.invokeAll(超时值,TimeUnit)与Future.get(超时,TimeUnit)

ExecutorService.invokeAll(超时值,TimeUnit)与Future.get(超时,TimeUnit)
EN

Stack Overflow用户
提问于 2017-12-20 13:27:31
回答 2查看 4.8K关注 0票数 2

我正在使用ExecutorService.invokeAll(Callable,超时值( TimeUnit)方法

在提交给ExecutorService的每个可调用的可调用函数中,我都有一个future.get()

即使future.get()已经超时,executorService ()还会在后台运行吗?

我是否也必须在future.get( timeout,TimeUnit)上指定超时,并抛出一个TimeoutException以确保未来被终止?

EN

回答 2

Stack Overflow用户

发布于 2018-01-05 18:16:18

正如文献资料所说:

返回时,尚未完成的任务将被取消。

它没有明确声明,但它使用Future.cancel(true),即中断正在运行的任务。由于Future.get()支持中断,这将导致它通过抛出一个InterruptedException来完成。如果您的Callable没有捕获它,也没有任何可能重置中断状态的内容,这意味着如果指定给invokeAll的超时时间过去了,这些调用将停止在Future.get()中等待。

然而,invokeAll只取消了未来,因此,发送中断信号,而不等待线程对其作出反应,并完成Callable代码的执行。因此,到那时,由于超时,invokeAll完成了,一些线程可能仍然运行在已经取消的任务上。但是,如果这些任务只是由一个future::get组成,那么这不应该是一个问题。

但是,如果您想要做的就是等待现有Future列表的完成,那么您可以更高效地完成这个任务。毕竟,您正在将每个Future封装到一个调用Future.getCallable中,invokeAll将将其封装到另一个Future中,可能会阻塞每个未来的一个工作线程,然后等待所有这些未来的完成。最后一步正是这个任务的意义所在,所以您可以不使用前面的步骤来完成它。

代码语言:javascript
复制
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); }
}

这基本上就是AbstractExecutorService在提交了所有Callable,为每个Callable创建了一个Future之后,等待所有未来的完成的方式。如前所述,如果您只想等待现有期货的列表,您可以通过向执行者提交作业来直接做到这一点,而不会浪费资源。使用这种方法的另一个好处是,这将取消原来的期货,而不仅仅是取消等待期货的工作。您还可以依赖此方法取消中断,而该属性没有为invokeAll显式指定,

票数 2
EN

Stack Overflow用户

发布于 2017-12-20 13:35:47

来自Javadoc

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

因此,1.所有结果都将由所有Callable提供,包括内部future.get()调用的结果;2.一旦invokeAll返回(在超时之前),所有期货都将终止。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47907133

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档