当前位置: 首页 > 知识库问答 >
问题:

执行服务。调用所有(超时,时间单位)与未来。获取(超时,时间单位)

姜煌
2023-03-14

我正在使用ExecutorService.invokeAll(Callable, timeout, TimeUnit)方法

在提交给ExecutorService的每个Callable中,我都有一个future.get()

未来会发生什么。即使executorService已超时,get()仍将在后台运行?

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

共有2个答案

扈俊健
2023-03-14

来自Javadoc

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

所以1。所有可调用的将提供所有结果,包括未来的结果。get()内部调用,2。一旦invokeAll返回(即在超时之前),所有期货都将终止。

杭泉
2023-03-14

正如文件所述:

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

虽然没有明确说明,但它使用了Future。取消(true),即中断正在运行的任务。因为未来。get()支持中断,这将通过抛出InterruptedException使其完成。如果您的Callable没有捕捉到它,也没有执行任何可能重置中断状态的操作,这意味着可调用项将在将来停止等待。get()如果指定给invokeAll的超时已过。

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

但是,如果你只想等待现有的未来的列表的完成,那么你可以更高效地完成这项工作。毕竟,您正在将每个未来包装成一个可调用的调用未来。get,它将invokeAll包装成另一个未来,可能会在每个未来阻塞一个工作线程,然后等待所有这些未来线程的完成。最后一步正是这项任务的目的,所以你可以不用前面的步骤来完成它,例如:。

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在提交了所有Callables之后等待所有期货完成的方式,为每个期货创建一个Future。如前所述,如果你想做的只是等待现有未来的列表,你可以直接这样做,而不需要通过向执行者提交作业来浪费资源。使用这种方法的另一个好处是,这将取消原始的期货,而不仅仅是取消等待期货的工作。您还可以依赖此方法中断取消,而此属性不是为invokeAll显式指定的,

 类似资料:
  • 我无法使用截击库。我不想无限期地等待请求,所以我不想设置超时。但它不起作用。我在其他地方也有同样的东西(我使用RequestFuture而不是RequestFuture),它运行良好,但在这里我无法将其设置为工作状态。 如果你能提供任何帮助,那就太棒了!谢谢

  • 文档有点混乱。如果超时,该方法将返回什么?文件上写着“计算结果”,但如果计算超时怎么办?它是空的吗? 谢谢

  • 代码: 如果花费时间超过1s(类似于网络的原因),那么另一个线程可以获得锁,但这会导致一些问题(例如超卖)。如果使用,当此客户端脱机时,它将永远不会解锁锁,其他客户端无法获得锁。如何解决或平衡这个问题?

  • 问题内容: 我正在编写一个利用JavaScript超时和间隔来更新页面的应用程序。有没有办法查看设置了多少间隔?我想确保不会因设置数百个间隔而意外杀死浏览器。 这甚至是个问题吗? 问题答案: 我不认为有一种方法来枚举活动的定时器,但是你可以重写,并与自己的实现其做一些跟踪,然后调用原件替换它们。 当然,您不一定总是调用,但这至少可以为您提供某种方式来跟踪运行时发生的情况。

  • 我使用命令生成器在Jenkins服务器上运行单元测试。phar exec“codecept运行单元应用程序/模型”-vvv并获取以下错误: [Symfony\Component\Process\Exception\ProcessTimedOutException] 进程“codecept运行单元应用程序/模型”超过了1800秒的超时时间。 我如何修复它并允许测试花费更多的时间?谢谢

  • 我正在调用while循环内的线程Hibernate1秒。当标志为true时,循环将运行(标志为true无限时间)。在循环内,线程应Hibernate1秒,唤醒并增加计数器,检查IF条件,如果为FALSE,则应再次Hibernate1秒并继续29次。在第30次迭代中,IF条件为true,IF语句中调用的方法将收集并存储数据。最后,在第32次迭代中,第二个IF语句将把存储的数据发送到服务器,并将计数设