这只是解释我的问题的一个例子......
我正在使用带有20个活动线程和75K最大排队项目的ExecutorService ...
在我的情况下,正常任务不应超过10秒,如果花费更多时间意味着任务有问题。
如果由于有问题的任务导致所有线程都挂起,我的RejectionHandler将重启整个服务。
我在这里有两个问题:
我不喜欢重启服务的想法,相反,如果有的话 检测挂起线程的方法,我们可以重新启动挂起 线程会很棒。我已经阅读了几篇文章来处理使用ThreadManager挂起的线程,但是没有找到任何东西 使用ExecutorService。
- 醇>
我对
Executors.newCachedThredPool()
非常着迷 因为在高峰期,我们负担过重的任务,并且 在其他日子里,他们很少。任何建议都会很大 赞赏。
public class HangingThreadTest {
// ExecutorService executorService = Executors.newCachedThreadPool()
private static ExecutorService executorService = new ThreadPoolExecutor(10,
20, 5L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(75000));
public static void main(String... arg0) {
for (int i = 0; i < 50000; i++) {
executorService.submit(new Task());
}
}
}
/**
* Task to be completed
*/
class Task implements Runnable {
private static int count = 0;
@Override
public void run() {
count++;
if (count%5 == 0) {
try {
System.out.println("Hanging Thread task that needs to be reprocessed: "
+ Thread.currentThread().getName()+" count: "+count);
Thread.sleep(11000);
} catch (InterruptedException e) {
// Do something
}
}
else{
System.out.println("Normal Thread: "
+ Thread.currentThread().getName()+" count: "+count);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//Do something
}
}
}
}
答案 0 :(得分:2)
Executors框架中没有内置机制可以帮助终止一个线程,如果它已经运行超过一个阈值。
但我们可以通过以下一些额外代码来实现这一目标:
executorService.submit(...);
返回的Future对象。 Future future = executorService.submit(new Task());
调用此future对象上的get
方法,并使其等待任务完成的阈值间隔。下面是一个等待仅2秒的例子。
try {
f.get(2, TimeUnit.SECONDS);
} catch (TimeoutException e) {
f.cancel(true);
} catch (Exception e) {}
上面的代码等待2秒完成任务,如果在此期间没有完成,它会抛出TimeoutException。随后我们可以在未来对象上调用cancel
方法。这导致在执行任务的线程中设置interrupt
标志。
Task
类代码中我们需要检查必要的点(取决于应用程序),interrupt
标志是否已使用isInterrupted()
方法设置为true Thread类。如果中断== true,我们可以立即进行必要的清理并从run
方法返回。这里的关键部分是确定Task类中您要检查此中断标志的必要点。这使线程可用于处理下一个任务。
答案 1 :(得分:0)
您可能会看一下这篇文章,在我遇到同样的问题之前对我非常有帮助:Java Hanging Thread Detection