如何等待 ThreadPoolExecutor 中的所有任务在超时内完成并且不关闭 Executor?

How to wait for all tasks within a ThreadPoolExecutor to finish within a timeout and without shutting the Executor down?

在使用 ThreadPoolExecutor 管理我的任务而不是为每个任务创建一个单独的线程之后。我使用以下部分来等待特定数量的任务完成:

poolThreadsExecutor.shutdown();
poolThreadsExecutor.awaitTermination(10, TimeUnit.MINUTES);
for (Future<List<String>> future : futures) {
    if (!future.isDone()) {
       future.cancel(true);
    }
}

使用此代码,我确保在 运行 完成之前不能提交新任务。 运行 任务也有超时,之后我检查期货列表并取消任何任务以防它被阻止。

通过这个方案我得到了我想要的所有点,但问题是执行器之后会被销毁,我必须每次都创建一个新的。

是否有可能在不关闭执行器的情况下获得相同的功能?

P.S.: 我也不能使用 CoundDownLatch,因为之前不知道任务的数量。

这将是解决方案的概要:

  1. 计算任务完成期限:deadline = currentTimeMillis() + timeout;
  2. 遍历所有期货,调用future.get(timeLeft, MILLISECONDS),每次调整timeLeft = deadline - currentTimeMillis()
  3. 如果到了最后期限,则跳出这个循环,进入取消循环。

final long deadline = System.currentTimeMillis() + timeout;
for (Future<?> f : futures) {
  final long timeLeft = deadline - System.currentTimeMillis();
  if (timeLeft <= 0) break;
  try {
    f.get(timeLeft, TimeUnit.MILLISECONDS);
  } catch (TimeoutException e) {
     break;
  }
}

for (Future<?> f : futures) {
  if (!future.isDone()) {
     future.cancel(true);
  }
}

不知道你是怎么提交任务的。但我看到你有一份期货清单。 如果您可以一次提交所有任务,您可以使用:

futures = poolThreadsExecutor.invokeAll(tasks, 10, TimeUnit.MINUTES);

它将执行您的任务,阻塞直到全部完成或超时到期(未完成的任务被取消)。

另外 Futures.successfulAsList 来自 guava 可能会有帮助。