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

Java:为线程池中的线程设置超时,java,multithreading,timeout,Java,Multithreading,Timeout,我想为线程池中执行的线程设置超时。目前我有以下代码: ExecutorService executor = Executors.newFixedThreadPool(8); for(List<String> l: partition) { Runnable worker = new WorkerThread(l); executor.execute(worker); } executor.shutdown(); while (!

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

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

executor.shutdown();
while (!executor.isTerminated()) {

}
到目前为止效果很好

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

if(Thread.interrupted()) {
    System.out.println("!!Thread -> " + Thread.currentThread().getName() + " INTERRUPTED!!");
        return;
}
因此,工作线程在超时后被“杀死”。这是一个好的解决方案吗

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

谢谢你的帮助

问候

你看到这个了吗

它应该正是您想要的:调用一个工作程序包,如果花费的时间太长,则让它们超时

评论后编辑-(新想法): 您可以使用来等待任务完成并通过
wait(长超时,时间单位)
超时! 然后你甚至可以立即关机,看看哪些任务花费的时间太长

编辑2:

更清楚地说:

  • 完成后,由每个工人进行倒计时
  • 在主执行线程中,等待所述锁存器超时
  • 当该调用返回时,您可以检查锁存器的计数,以查看是否有超时命中(如果大于0)
  • a) 计数=0,所有任务都按时完成。 b) 如果没有,则循环期货并检查其
    isDone
    。您不必调用Executor服务上的shutdown
  • 如果不再需要执行器,请调用shutdown

  • 注意:工作人员可以在超时和调用其未来的isDone()之间的这段时间内完成。是的,它适用于更多,只需在列表中保留未来。请不要以这种方式考虑线程。正在执行某些操作,如果需要的时间超过一定的时间,则需要超时。这不是任何线程可能会做的工作,这是工作。也许有两个线程正在协作工作。可能当时没有线程在处理该工作。但这是您想要停止或超时的工作,而不是可能正在或可能不正在处理的一个或多个线程。这种微妙的视角转换对于正确思考线程非常重要,这样你就可以得到好的设计。@DavidSchwartz很好的观点,但是可能存在这样的情况,即作品之间完全独立。我不知道OP是否真的考虑过这个问题,但看起来这里就是这样。@fge:这不是作品之间的关系。这是关于“工作”(需要完成的事情)的概念,它不同于正在做它的线程。如果工作正在等待某个内容,则没有线程与之关联。如果工作可以并发完成,那么多个线程可能会协作完成。当你在等待一些工作完成时,你不应该考虑什么线程或线程(如果有的话)正在处理它。好吧……不过我必须调用“executor.shutdown()”来等待线程是否完成,对吗?不一定。你仍然可以在未来的每一个周期中轮询一个轮询ISONE()或调用GET(),或者你可以使用A,我认为后者是“最好”的方式。“倒计时锁”看起来很不错。你说(在你的“编辑”行中)我可以在呼叫Wait后立即运行关机。因此,方法shutdownNow将取消由于设置的超时而仍在运行的所有线程?这是我的下一个问题,因为我无法使用invokeAll找出哪些线程“违反”了超时。也许有了新的方法,这是可能的?只有轻微的变化。您将在CountDownLatch实例上调用wait,并超时。该调用将一直阻塞,直到达到超时或闩锁降至0。之后,您可以立即关机,它将返回。。。啊,刚刚读到,现在关机只返回未开始的任务。但是你仍然可以迭代未来并询问他们是否完成了:)好的,但是如果我迭代未来并询问他们是否完成了,我必须调用shutdown()或shutdownNow()。在没有调用shutdown()的情况下执行此操作时,我得到一个“java.util.concurrent.CancellationException”:List=executor.invokeAll(tasks,1,TimeUnit.SECONDS);对于(Future fut:list){if(fut.isDone()){System.out.println(“任务”+fut.get()+“已完成”);}}Future返回一个带有线程名称的字符串。编辑:不使用“倒计时闩锁”
    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?!
        }
        }
    }
    
    if(Thread.interrupted()) {
        System.out.println("!!Thread -> " + Thread.currentThread().getName() + " INTERRUPTED!!");
            return;
    }