等待一批期货完成时超时?

时间:2013-07-02 19:35:46

标签: java concurrency future java.util.concurrent

我通过向Futures提交Callable来创建一组Executor。伪代码:

for all tasks
  futures.add(executor.submit(new callable(task)))

现在我希望所有的期货最多等待n秒,直到全部完成。我知道我可以打电话给Future#get(timeout),但是如果我在循环中按顺序拨打所有我的未来,则会有时间加起来。伪代码:

for all futures
  future.get(timeout)

get阻塞超时,直到结果准备好。因此,如果第一个在超时之前完成,第二个也在超时之前完成,那么整个执行时间最多为number of futures * timeout而不是timeout

因此,我正在寻找一种接受Future列表和超时的方法,并行运行,然后返回未来结果的集合。有什么想法吗?

1 个答案:

答案 0 :(得分:7)

您可以使用ExecutorService.invokeAll

  

执行给定的任务,返回一个Futures列表,在完成或超时到期时保持其状态和结果,以先发生者为准。对于返回列表的每个元素,Future.isDone()都为true。返回时,未完成的任务将被取消。请注意,已完成的任务可能正常终止或通过抛出异常终止。如果在此操作正在进行时修改了给定集合,则此方法的结果未定义。


如果您已经需要监控Future并且无法使用invokeAll,则可以自行测量超时。伪代码:

long endTime = System.currentTimeMillis() + timeoutMS;
for(f : futures)
    f.get(Math.max(0, endTime - System.currentTimeMillis()), TimeUnit.MILLISECONDS);

通过这种方式,您可以为每个未来提供最长时间,直到达到超时为止。