Java:为线程池中的线程设置超时



我想为在线程池中执行的线程设置超时。目前我有以下代码:

ExecutorService executor = Executors.newFixedThreadPool(8);
for(List<String> l: partition) {            
    Runnable worker = new WorkerThread(l);
    executor.execute(worker);
}       
executor.shutdown();
while (!executor.isTerminated()) {
}

该代码只是将一个大的对象列表拆分为子列表,并在单个线程中处理这些子列表。但这不是重点。

我想给线程池中的每个线程一个超时。对于池中只有一个线程,我找到了以下解决方案:

Future<?> future = null;
for (List<String> l : partition) {
    Runnable worker = new WorkerThread(l);
    future = executor.submit(worker);
}
try {
    System.out.println("Started..");
    System.out.println(future.get(3, TimeUnit.SECONDS));
    System.out.println("Finished!");
} catch (TimeoutException e) {
    System.out.println("Terminated!");
}

但这不会适用于多个线程。也许我必须把每个线程放在一个List<Future>列表中,然后迭代这个列表,并为每个future对象设置一个超时?

有什么建议吗?

使用CountDownLatch:后编辑

CountDownLatch doneSignal = new CountDownLatch(partition.size());
List<Future<?>> tasks = new ArrayList<Future<?>>();
ExecutorService executor = Executors.newFixedThreadPool(8);
for (List<String> l : partition) {
    Runnable worker = new WorkerThread(l);
    tasks.add(executor.submit(doneSignal, worker));
}
doneSignal.await(1, TimeUnit.SECONDS);
if (doneSignal.getCount() > 0) {
    for (Future<?> fut : tasks) {
    if (!fut.isDone()) {
        System.out.println("Task " + fut + " has not finshed!");
        //fut.cancel(true) Maybe we can interrupt a thread this way?!
    }
    }
}

到目前为止效果不错。

所以下一个问题是如何中断超时的线程?我尝试fut.cancel(true),并在工作线程的一些关键循环中添加以下结构:

if(Thread.interrupted()) {
    System.out.println("!!Thread -> " + Thread.currentThread().getName() + " INTERRUPTED!!");
        return;
}

因此,工作线程在超时后被"杀死"。这是一个好的解决方案吗?

此外:是否可以通过Future接口获取超时线程的名称?目前,我必须打印出Thread.interrupted()构造的if条件中的名称。

谢谢你的帮助!

问候

你看到这个了吗?ExecutiorService.invokeAll

这应该正是您想要的:调用一个工作者束,如果花费太长时间,则让他们超时。

评论后编辑-(新想法(:您可以使用CountDownLatch通过await(long timeout, TimeUnit unit)等待任务完成AND超时!然后你甚至可以做一个shutdownNow,看看哪些任务花了太长时间。。。

编辑2:

为了更清楚:

  1. 完成后,让每个工人倒计时一个CountDownLatch
  2. 在所述锁存器上具有超时的主执行线程CCD_ 7中
  3. 当该调用返回时,您可以检查Latches的计数,看看是否有超时命中(如果它>0(
  4. a( count=0,所有任务都及时完成。b( 如果没有,则循环Futures并检查它们的isDone。您不必在ExecutorService上调用shutdown
  5. 如果您不再需要Executor,请调用shutdown

注意:工人可以在超时和调用Future的isDone((之间的时间内完成。

Future future = executorService.submit(callable)
future.get(timeout, unit)

有关详细信息,请参阅此链接。

相关内容

  • 没有找到相关文章

最新更新