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

时间:2009-08-24 16:30:11

标签: java multithreading jvm

有什么方法可以获取当前JVM中所有正在运行的线程的列表(包括我的类启动的的线程)?

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

我希望能够通过代码执行此操作。

13 个答案:

答案 0 :(得分:287)

获得可迭代集:

Set<Thread> threadSet = Thread.getAllStackTraces().keySet();

答案 1 :(得分:67)

获取根ThreadGroup的句柄,如下所示:

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(),直到数组足够大以包含所有条目。

答案 2 :(得分:26)

是的,请看getting a list of threads。该页面上有很多例子。

这是以编程方式进行的。如果你只想在Linux上找到一个列表,至少可以使用这个命令:

kill -3 processid

并且VM将执行到stdout的线程转储。

答案 3 :(得分:17)

您可以从ThreadMXBean获取有关线程的大量信息。

调用静态ManagementFactory.getThreadMXBean()方法获取对MBean的引用。

答案 4 :(得分:13)

您是否看过 jconsole

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

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

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

答案 5 :(得分:5)

Groovy 中,您可以调用私有方法

// Get a snapshot of the list of all threads 
Thread[] threads = Thread.getThreads()

Java 中,您可以使用安全管理器允许的反射来调用该方法。

答案 6 :(得分:4)

您可以尝试这样的事情:

Thread.getAllStackTraces().keySet().forEach((t) -> System.out.println(t.getName() + "\nIs Daemon " + t.isDaemon() + "\nIs Alive " + t.isAlive()));

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

答案 7 :(得分:4)

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

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();
        }
    }
}

输出:

Thread :Thread[MyThread:2,5,main]:state:TIMED_WAITING
Thread :Thread[MyThread:0,5,main]:state:TIMED_WAITING
Thread :Thread[MyThread:1,5,main]:state:TIMED_WAITING
Thread :Thread[ThreadSet,5,main]:state:RUNNABLE

如果您需要包含尚未由您的程序启动的系统线程的所有线程,请删除以下条件。

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

答案 8 :(得分:3)

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

答案 9 :(得分:3)

    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 + "  ");
        }
    }

答案 10 :(得分:3)

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

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

答案 11 :(得分:0)

答案 12 :(得分:0)

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

jstack -l <PID>

哪个PID是计算机上正在运行的进程的ID。要获取Java进程的进程ID,您只需运行以下命令即可:

jsp

您还可以分析jstack在TDA(线程转储分析器)中生成的线程转储,例如fastthreadspotify thread analyzer tool