我想为在线程池中执行的线程设置超时。目前,我有下面的代码:Java:为ThreadPool中的线程设置超时
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>
列表中,并遍历这个列表并为每个对象设置一个超时时间?
有什么建议吗?
编辑使用CountDownLatch AFTER:
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条件中打印出名称。
感谢您的帮助!
Regards
是的,它适用于更多,只是将期货保持在列表中。 – Fildor
请不要用这种方式来思考线程。有些事情正在完成,如果需要超过一定的时间,则需要超时。这不是什么线索可能发生在做这项工作,它是*工作*。也许两个线程正在进行合作。当时可能没有线程正在处理那项工作。但它是你想要停止或超时的*工作*,而不是可能或可能不会发生的线程或线程。这种细微的观点转变对正确思考线程非常重要,这样您就可以收到良好的设计。 –
@DavidSchwartz好点,但是可能有些作品是完全独立于彼此的情况。我不知道OP是否确实是这样,但在这里看起来就是这样。 – fge