是否有任何方法可以获得当前JVM中所有正在运行的线程的列表(包括不是由我的类启动的线程)?

是否也可以获得列表中所有线程的Thread和Class对象?

我希望能够通过代码来实现。


当前回答

Apache Commons用户可以使用ThreadUtils。当前实现使用前面概述的线程组方法。

for (Thread t : ThreadUtils.getAllThreads()) {
      System.out.println(t.getName() + ", " + t.isDaemon());
}

其他回答

获取根线程组的句柄,像这样:

ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
ThreadGroup parentGroup;
while ((parentGroup = rootGroup.getParent()) != null) {
    rootGroup = parentGroup;
}

现在,在根组上重复调用enumerate()函数。第二个参数让你递归地获取所有线程:

Thread[] threads = new Thread[rootGroup.activeCount()];
while (rootGroup.enumerate(threads, true ) == threads.length) {
    threads = new Thread[threads.length * 2];
}

注意我们如何反复调用enumerate(),直到数组大到足以包含所有条目。

Apache Commons用户可以使用ThreadUtils。当前实现使用前面概述的线程组方法。

for (Thread t : ThreadUtils.getAllThreads()) {
      System.out.println(t.getName() + ", " + t.isDaemon());
}

要使用终端获取线程列表及其完整状态,您可以使用下面的命令:

jstack -l <PID>

>是在您的计算机上运行的进程的id。要获得java进程的进程id,可以简单地运行jps命令。

此外,您还可以在TDAs(线程转储分析器)(fastthread或spotify线程分析工具)中分析jstack生成的线程转储。

您可以使用返回所有活动线程id的getAllThreadIds。当此方法返回时,返回数组中包含的某些线程可能已经终止。

ManagementFactory.getThreadMXBean().getAllThreadIds()

在java控制台中,点击Ctrl-Break。它将列出所有线程以及堆的一些信息。当然,这不会让您访问对象。但无论如何,它对调试都很有帮助。