我希望为在线程池中执行的线程设置超时时间。目前我有以下代码:
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()
结构的条件语句中打印出名称。
谢谢帮助!
祝好