Получить список всех потоков, работающих в настоящее время в Java

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

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

Я хочу быть в состоянии сделать это с помощью кода.

Ответ 1

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

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

Ответ 2

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

Ответ 3

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

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

kill -3 processid

и VM выполнит сброс потока в stdout.

Ответ 4

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

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

Ответ 5

Вы взглянули на jconsole?

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

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

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

Ответ 6

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

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

Ответ 7

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

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

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

Ответ 8

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

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

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

Ответ 9

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

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

Ответ 10

В консоли java нажмите Ctrl-Break. Он перечислит все потоки и некоторую информацию о куче. Это не даст вам доступ к объектам, конечно. Но это может быть очень полезно для отладки в любом случае.

Ответ 11

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

Ответ 13

Чтобы получить список потоков и их полных состояний с помощью терминала, вы можете использовать команду ниже:

jstack -l <PID>

Какой PID является идентификатором процесса, запущенного на вашем компьютере. Чтобы получить идентификатор процесса вашего Java-процесса, вы можете просто запустить следующую команду:

jps

Кроме того, вы можете анализировать дамп потока, созданный jstack, в TDA (Thread Dump Analyzer), например, fastthread или инструмент анализатора спойтов потока.