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

Mar*_*tör 8 java concurrency future java.util.concurrent

我有一组Futures通过提交Callables来创建Executor.伪代码:

for all tasks
  futures.add(executor.submit(new callable(task)))
Run Code Online (Sandbox Code Playgroud)

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

for all futures
  future.get(timeout)
Run Code Online (Sandbox Code Playgroud)

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

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

Pet*_*lák 9

你可以使用ExecutorService.invokeAll:

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


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

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

这样,您最多可以为每个未来提供剩余的持续时间,直到达到超时.