我有一个多线程应用程序。该应用程序接收并在不同的线程中处理多个消息。为此,我使用了java.util.concurrent包中的ThreadPoolExecutor和FutureTask类。
偶尔会发生死锁。当发生死锁时,我想中断被阻塞的线程,并记录该线程的堆栈跟踪,以便稍后解决死锁问题。
在Java中,是否有一种方法可以在该线程之外找到线程的堆栈跟踪?
我有一个多线程应用程序。该应用程序接收并在不同的线程中处理多个消息。为此,我使用了java.util.concurrent包中的ThreadPoolExecutor和FutureTask类。
偶尔会发生死锁。当发生死锁时,我想中断被阻塞的线程,并记录该线程的堆栈跟踪,以便稍后解决死锁问题。
在Java中,是否有一种方法可以在该线程之外找到线程的堆栈跟踪?
您可以在应用程序内部定期记录所有线程的堆栈跟踪(或在终止进程之前),使用以下方法:
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分钟,如果仍然出现死锁,则记录所有堆栈跟踪,如上所述。
在进入死锁区域之前,设置一个字段,例如:
thread = Thread.currentThread();
我不确定您是否希望从同一JVM内部获取堆栈跟踪,还是希望使用外部工具获取堆栈跟踪,但如果您希望使用外部工具获取堆栈跟踪,则以下内容将有所帮助:
是和不是。您可以从其他虚拟机中转储线程,但它们的堆栈跟踪可能并不像您认为的那样有用,以确定死锁原因。如果 JVM(在您的应用程序虚拟机上)检测到了真正的死锁,您应该拥有调试原因所需的一切(或多或少)。