Получить список всех потоков, работающих в настоящее время в Java - PullRequest
211 голосов
/ 24 августа 2009

Можно ли как-нибудь получить список всех запущенных потоков в текущей JVM (включая потоки , а не , запущенные моим классом)?

Можно ли также получить объекты Thread и Class всех потоков в списке?

Я хочу сделать это с помощью кода.

Ответы [ 12 ]

287 голосов
/ 11 июня 2010

Чтобы получить повторяемый набор:

Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
67 голосов
/ 24 августа 2009

Получить дескриптор корня 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 (), пока массив не станет достаточно большим, чтобы содержать все записи.

26 голосов
/ 24 августа 2009

Да, посмотрите на получение списка тем . Много примеров на этой странице.

Это делается программно. Если вам нужен хотя бы список в Linux, вы можете просто использовать эту команду:

kill -3 processid

и виртуальная машина сделает дамп потока в стандартный вывод.

17 голосов
/ 24 августа 2009

Вы можете получить много информации о темах из ThreadMXBean .

Вызов статического ManagementFactory.getThreadMXBean () метода для получения ссылки на MBean.

13 голосов
/ 24 августа 2009

Вы смотрели на jconsole ?

В этом списке будут перечислены все потоки, запущенные для определенного процесса Java.

Вы можете запустить jconsole из папки bin JDK.

Вы также можете получить полную трассировку стека для всех потоков, нажав Ctrl+Break в Windows или отправив kill pid --QUIT в Linux.

5 голосов
/ 12 июля 2013

В Groovy вы можете вызывать частные методы

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

В Java этот метод можно вызывать с помощью отражения, если это разрешено диспетчером безопасности.

4 голосов
/ 30 июля 2016

Фрагмент кода для получения списка потоков, созданных основным потоком:

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
4 голосов
/ 16 мая 2016

Вы можете попробовать что-то вроде этого:

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

и вы можете получить больше характеристик потока, если вам нужно.

3 голосов
/ 11 апреля 2018

Пользователи Apache Commons могут использовать ThreadUtils. Текущая реализация использует ранее описанный подход с использованием групповых потоков.

for (Thread t : ThreadUtils.getAllThreads()) {
      System.out.println(t.getName() + ", " + t.isDaemon());
}
3 голосов
/ 24 августа 2009
    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 + "  ");
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...