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:
更清楚地说:
isDone
。您不必调用Executor服务上的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;
}