Java线程:找出仍在运行的线程

3

出于调试目的,我想找出程序中仍在运行的线程。似乎有一个或多个线程意外地没有被中断。某种漂亮的可打印格式将是一个额外的奖励。

5个回答

5
使用'jps'命令行工具查看活动的Java进程,使用'jstack'显示活动线程。

jstack文档

示例


3
如果您正在寻找编程解决方案,类似于以下代码(在JDK 1.5或更高版本中)应该可以解决问题:
Map<Thread, StackTraceElement[]> stack = Thread.getAllStackTraces();
for (Map.Entry<Thread, StackTraceElement[]> entry : stack.entrySet()) {
    System.out.println("Thread named '" + 
                       entry.getKey().getName() + 
                       "' is alive");
}

1
+1 对于 Java 实现(我不知道这是可能的) - Petro Semeniuk
嘘,你可以直接遍历 stack.keySet() 而不是获取 Entrys 并忽略值。它与你的代码完全相同,但在我看来更清晰(没有必须使用值的感觉...)。 - Andrzej Doyle

3

jVisualVM 是针对这种调试情况的好帮手。它位于 JDK 安装目录下的 /bin 目录中。以图形视图显示所有线程,并允许您深入了解它们正在执行的操作。 Thread Dump 按钮将打印出它们的所有当前堆栈跟踪,以便您查看用户代码是否被卡住。


1
JVisualVM是一个很棒的工具。我更喜欢使用JConsole来检查单个线程,但是JVisualVM的线程转储功能非常好。不过我希望它可以将转储内容显示在允许文本搜索/高亮的界面上。 - Tim Bender
我使用fgrep来查找文本。例如,jstack <PID> | fgrep "com.bla.foo"。 - Petro Semeniuk
1
您仍然可以通过JMX控制在jconsole中转储线程。 - Toby

1

对你的回答点个赞+1并给tempus-fugit加上100000分。除了项目名称十分无脑之外,这显然非常便捷 :) - SyntaxT3rr0r

0

似乎有一个或多个线程意外地没有被中断。我不会说事情没有被中断。调用Thread.interrupt()并不能强制可运行的程序停止。它设置了中断标志,并可能导致阻塞操作(如Thread.sleep或java.nio调用)抛出InterruptedException或其他异常(如nio的ClosedByInterruptException)。您的可运行程序必须检查Thread.currentThread().isInterrupted()并表现得友好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接