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

时间:2015-01-20 11:11:22

标签: java multithreading executorservice

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

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

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

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

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

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

2 个答案:

答案 0 :(得分:4)

这将是一个解决方案的概述:

  1. 计算任务完成的截止日期:deadline = currentTimeMillis() + timeout;
  2. 遍历所有未来,每次调整future.get(timeLeft, MILLISECONDS);
  3. 时调用timeLeft = deadline - currentTimeMillis()
  4. 如果达到截止日期,则跳出此循环并进入取消循环。

  5. 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);
      }
    }
    

答案 1 :(得分:1)

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

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

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

来自番石榴的Futures.successfulAsList也许会有所帮助。