我有一个多线程应用程序。几条消息到达应用程序,并在分离的线程中处理。为此,我使用java.util.concurrent包中的ThreadPoolExecutor和FutureTask类。如何获取线程的堆栈跟踪
偶尔我在应用程序中有一些死锁。当发生死锁时,我想中断阻塞线程,并且我想记录此线程的堆栈跟踪,以便稍后解决死锁问题。
有什么办法可以在Java中找到线程之外的线程的堆栈跟踪吗?
我有一个多线程应用程序。几条消息到达应用程序,并在分离的线程中处理。为此,我使用java.util.concurrent包中的ThreadPoolExecutor和FutureTask类。如何获取线程的堆栈跟踪
偶尔我在应用程序中有一些死锁。当发生死锁时,我想中断阻塞线程,并且我想记录此线程的堆栈跟踪,以便稍后解决死锁问题。
有什么办法可以在Java中找到线程之外的线程的堆栈跟踪吗?
请参阅here了解如何生成堆栈跟踪,包括如何以编程方式执行此操作。从控制台,Ctrl + Break将堆栈跟踪转储到标准输出。有关更多详细信息,另请参阅this SO question。
在UNIX环境中,向java进程发送“QUIT”('kill -QUIT
您可以不时从应用程序中记录所有线程的堆栈跟踪(或在杀死进程之前)。要做到这一点使用:
Map<Thread, StackTraceElement[]> m = Thread.getAllStackTraces();
for(Map.Entry<Thread, StackTraceElement[]> e : m.entrySet()) {
log(e.getKey().toString());
for (StackTraceElement s : e.getValue()) {
log(" " + s);
}
}
当运行夜间自动化测试时,有时某些测试用例会陷入死锁。我添加了一个“TimeBomb”守护程序线程,等待30分钟,然后如上所述记录所有堆栈跟踪。
我不知道,如果你想从同一个JVM或外部内获得堆栈跟踪,但如果你想获得与外部工具堆栈跟踪,下面会有所帮助:
您使用JStack。这里有一个很好的blog entry,详细介绍了如何获取堆栈跟踪。
进入僵局区域之前,设置一个字段一样,
thread = Thread.currentThread();
在你的监视线程可以执行thread.getStackTrace();获得该线程的堆栈跟踪在任何时间。
发生死锁时我要中断阻塞线程...
您可以实现周期性任务检查死锁(其中死锁是Java的内在或Lock
为主)和呼叫interrupt
涉及场景中涉及的所有线程。但是,这并不能保证它能解决你的问题。它可能会再次发生。有关详细信息,请参见Dr Heinz's article on a deadlock detector。
如果事实上,并不能保证interrupt
甚至可以释放像这样的阻止进程。例如,通过使用超时和重试策略的锁定或“在您购买之前尝试”方法,它首先可以更好地避免死锁情况。
,我想记录该线程的堆栈跟踪...
如果你想这样做编程,再次,遵守亨氏博士的例子。如果没有,只要在发现问题时生成线程转储。
有什么办法,我们如何找到Java线程之外的线程的堆栈跟踪?
是和否。您可以转储来自其他虚拟机的线程,但是它们的堆栈跟踪可能不如您想象的那样有用,以确定死锁的原因。如果检测到真正的死锁(由JVM本身在线程转储您的应用程序虚拟机上),您应该拥有调试原因所需的所有东西(或多或少)。
你的意思是你想检测死锁并恢复?从来没有这样做过,但使用堆栈跟踪听起来并不像我正确的方式.. – 2010-09-17 11:01:26
我需要堆栈跟踪,以便我知道线程卡住的位置,并且可以解决问题,以便应用程序可以正常工作重新开始。不过,我想中断阻塞线程,以便应用程序可以工作,直到找到一些时间来解决问题并释放它。 – Palo 2010-09-17 11:10:38