获取当前在Java中运行的所有线程的列表

获取当前在Java中运行的所有线程的列表,java,multithreading,jvm,Java,Multithreading,Jvm,是否有任何方法可以获取当前JVM中所有正在运行的线程的列表(包括我的类未启动的线程) 是否也可以获取列表中所有线程的线程和类对象 我希望能够通过代码实现这一点。是的,请查看。那页上有很多例子 这就是通过编程来实现的。如果您只需要Linux上的列表,至少可以使用以下命令: kill -3 processid 虚拟机将向stdout进行线程转储。您看过jconsole了吗 这将列出为特定Java进程运行的所有线程 您可以从JDK-bin文件夹启动jconsole 您还可以通过在Windows中点击

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

是否也可以获取列表中所有线程的
线程
对象

我希望能够通过代码实现这一点。是的,请查看。那页上有很多例子

这就是通过编程来实现的。如果您只需要Linux上的列表,至少可以使用以下命令:

kill -3 processid

虚拟机将向stdout进行线程转储。

您看过jconsole了吗

这将列出为特定Java进程运行的所有线程

您可以从JDK-bin文件夹启动jconsole


您还可以通过在Windows中点击
Ctrl+Break
或在Linux中发送
kill-pid--QUIT
来获取所有线程的完整堆栈跟踪。

获取根
线程组的句柄,如下所示:

ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
ThreadGroup parentGroup;
while ((parentGroup = rootGroup.getParent()) != null) {
    rootGroup = parentGroup;
}
Thread.getAllStackTraces().keySet().forEach((t) -> System.out.println(t.getName() + "\nIs Daemon " + t.isDaemon() + "\nIs Alive " + t.isAlive()));
现在,对根组重复调用
enumerate()
函数。第二个参数用于递归获取所有线程:

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

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

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

您可以从中获得很多关于线程的信息

调用static方法以获取对MBean的引用。

publicstaticvoidmain(String[]args){
    public static void main(String[] args) {


        // Walk up all the way to the root thread group
        ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
        ThreadGroup parent;
        while ((parent = rootGroup.getParent()) != null) {
            rootGroup = parent;
        }

        listThreads(rootGroup, "");
    }


    // List all threads and recursively list all subgroup
    public static void listThreads(ThreadGroup group, String indent) {
        System.out.println(indent + "Group[" + group.getName() + 
                ":" + group.getClass()+"]");
        int nt = group.activeCount();
        Thread[] threads = new Thread[nt*2 + 10]; //nt is not accurate
        nt = group.enumerate(threads, false);

        // List every thread in the group
        for (int i=0; i<nt; i++) {
            Thread t = threads[i];
            System.out.println(indent + "  Thread[" + t.getName() 
                    + ":" + t.getClass() + "]");
        }

        // Recursively list all subgroups
        int ng = group.activeGroupCount();
        ThreadGroup[] groups = new ThreadGroup[ng*2 + 10];
        ng = group.enumerate(groups, false);

        for (int i=0; i<ng; i++) {
            listThreads(groups[i], indent + "  ");
        }
    }
//一直走到根线程组 ThreadGroup rootGroup=Thread.currentThread().getThreadGroup(); 线程组父级; 而((parent=rootGroup.getParent())!=null){ 根组=父; } listThreads(根组“”); } //列出所有线程并递归列出所有子组 公共静态无效列表线程(线程组、字符串缩进){ System.out.println(缩进+“组[”+Group.getName()+ “:“+group.getClass()+”]”; int nt=group.activeCount(); 线程[]线程=新线程[nt*2+10];//nt不准确 nt=组枚举(线程,false); //列出组中的每个线程
对于(int i=0;i获得可数集:

Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
Set threadSet=Thread.getAllStackTraces().keySet();
在Groovy中,您可以调用私有方法

// Get a snapshot of the list of all threads 
Thread[] threads = Thread.getThreads()
在Java中,如果安全管理器允许,您可以使用反射调用该方法。

您可以使用反射返回所有活动线程ID。当该方法返回时,返回数组中包含的某些线程可能已终止

ManagementFactory.getThreadMXBean().getAllThreadIds()

您可以尝试以下方法:

ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
ThreadGroup parentGroup;
while ((parentGroup = rootGroup.getParent()) != null) {
    rootGroup = parentGroup;
}
Thread.getAllStackTraces().keySet().forEach((t) -> System.out.println(t.getName() + "\nIs Daemon " + t.isDaemon() + "\nIs Alive " + t.isAlive()));

如果需要,您显然可以获得更多的线程特征。

获取由主线程启动的线程列表的代码片段:

import java.util.Set;

public class ThreadSet {
    public static void main(String args[]) throws Exception{
        Thread.currentThread().setName("ThreadSet");
        for ( int i=0; i< 3; i++){
            Thread t = new Thread(new MyThread());
            t.setName("MyThread:"+i);
            t.start();
        }
        Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
        for ( Thread t : threadSet){
            if ( t.getThreadGroup() == Thread.currentThread().getThreadGroup()){
                System.out.println("Thread :"+t+":"+"state:"+t.getState());
            }
        }
    }
}

class MyThread implements Runnable{
    public void run(){
        try{
            Thread.sleep(5000);
        }catch(Exception err){
            err.printStackTrace();
        }
    }
}
如果您需要包括系统线程在内的所有线程,而这些线程尚未由您的程序启动,请删除以下条件

if ( t.getThreadGroup() == Thread.currentThread().getThreadGroup())
现在输出:

Thread :Thread[MyThread:2,5,main]:state:TIMED_WAITING
Thread :Thread[Reference Handler,10,system]:state:WAITING
Thread :Thread[MyThread:1,5,main]:state:TIMED_WAITING
Thread :Thread[ThreadSet,5,main]:state:RUNNABLE
Thread :Thread[MyThread:0,5,main]:state:TIMED_WAITING
Thread :Thread[Finalizer,8,system]:state:WAITING
Thread :Thread[Signal Dispatcher,9,system]:state:RUNNABLE
Thread :Thread[Attach Listener,5,system]:state:RUNNABLE

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

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

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

jstack -l <PID>
jstack-l
哪个
是计算机上运行的进程id。要获取java进程的进程id,只需运行
jps
命令即可


此外,您还可以在TDAs(线程转储分析器)中分析jstack生成的线程转储这样或那样。

我想访问java classIn中的列表,在这种情况下,请看cletus的答案。嗯,为什么当这个家伙说他想要一个编程解决方案时,人们会投票支持这个问题?因为问题没有说明这一点。我会编辑问题使其显式。kill-3?至少在我的linux上,这是“终端退出”CalEPS确实是正确的-杀死3将线程转储到STDUT,不管信号意味着什么。我会考虑使用JStAt替代。无法达到:NaDaUsOfTeaRead拒绝连接。我感到震惊的是,这种策略在互联网上如此流行。方法更简单(1行代码)。乔希·沃尔夫:事实上,我同意——我认为你的答案要好得多,如果不是晚了一年的话,它本来可能是被接受的答案。如果OP仍然经常光顾,他显然是这样,他最好不要接受我的ans请注意,除了
根组
,您应该使用
新线程[rootGroup.activeCount()+1]
activeCount()
可能为零,如果为零,您将运行到一个无限循环中。@thejoshwolfe我想这个解决方案的成本要低得多。+1对于这个被低估的答案,因为它更适合于IMHO的监控目的。其固有的竞争条件在监控中并不重要。但是,正如一些快速的“n”脏测试所显示的,它大约是70-80倍比基于stacktrace的解决方案更快。对于监控,一个小的性能印记是必不可少的,因为您希望使对监控系统的影响尽可能小(海森堡再次罢工:)对于调试,您可能需要更可靠的信息,stacktrace方法可能是必不可少的。顺便说一句,MxBean解决方案甚至比使用stacktraces更慢。虽然比建议的另一种方法更干净,但这有一个缺点,即会导致为所有线程获取堆栈跟踪的成本。如果您将使用这些堆栈跟踪无论如何,这显然是优越的。如果不是,那么除了干净的代码之外,这可能会非常慢,没有任何好处。@Eddie,这是常识的假设,还是你做过实验?“非常慢”你说;慢了多少?值得吗?我问