Ottieni un elenco di tutti i thread attualmente in esecuzione in Java


C'è un modo per ottenere un elenco di tutti i thread in esecuzione nella JVM corrente (inclusi i thread NON avviati dalla mia classe)?

È anche possibile ottenere gli oggetti Thread e Class di tutti i Thread nell'elenco?

Voglio essere in grado di farlo attraverso il codice.

Author: BIBD, 2009-08-24

12 answers

Per ottenere un set iterabile:

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

Per convertirlo in un array:

Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]);
 271
Author: thejoshwolfe, 2010-06-10 21:28:46

Ottieni un handle alla radice ThreadGroup, in questo modo:

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

Ora, chiamare ripetutamente la funzione enumerate() sul gruppo radice. Il secondo argomento consente di ottenere tutti i thread, in modo ricorsivo:

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

Nota come chiamiamo enumerate() ripetutamente fino a quando l'array è abbastanza grande da contenere tutte le voci.

 64
Author: Frerich Raabe, 2018-07-03 08:55:21

Sì, dai un'occhiata a ottenendo un elenco di thread. Un sacco di esempi su quella pagina.

Questo per farlo a livello di programmazione. Se vuoi solo una lista su Linux almeno puoi usare questo comando:

kill -3 processid

E la VM eseguirà un dump del thread su stdout.

 25
Author: cletus, 2009-08-24 16:31:37

È possibile ottenere molte informazioni sui thread dal ThreadMXBean.

Chiama la funzione di gestione statica .getThreadMXBean () metodo per ottenere un riferimento al MBean.

 16
Author: Dan Dyer, 2009-08-24 17:05:29

Hai dato un'occhiata a jconsole ?

Questo elencherà tutti i thread in esecuzione per un particolare processo Java.

È possibile avviare jconsole dalla cartella JDK bin.

È anche possibile ottenere una traccia completa dello stack per tutti i thread premendo Ctrl+Break in Windows o inviando kill pid --QUIT in Linux.

 11
Author: pjp, 2009-08-24 16:31:44

In Groovy puoi chiamare metodi privati

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

In Java, è possibile richiamare tale metodo utilizzando reflection a condizione che security manager lo consenta.

 4
Author: Jarek Przygódzki, 2015-07-23 10:02:20

Nella console java, premere Ctrl-Break. Elencherà tutti i thread più alcune informazioni sull'heap. Questo non ti darà accesso agli oggetti, naturalmente. Ma può essere molto utile per il debug comunque.

 3
Author: raoulsson, 2014-02-25 07:58:30

Puoi provare qualcosa del genere:

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

E ovviamente puoi ottenere più caratteristiche del thread se ne hai bisogno.

 3
Author: hasskell, 2018-07-03 08:54:33
    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 + "  ");
        }
    }
 2
Author: ZZ Coder, 2009-08-24 17:15:30

Snippet di codice per ottenere l'elenco dei thread avviati dal thread principale:

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

Uscita:

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

Se hai bisogno di tutti i thread, inclusi i thread di sistema, che non sono stati avviati dal tuo programma, rimuovi sotto condizione.

if ( t.getThreadGroup() == Thread.currentThread().getThreadGroup())

Ora in uscita:

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
 2
Author: Ravindra babu, 2016-07-30 15:19:37

Gli utenti di Apache commons possono usare ThreadUtils. L'implementazione corrente utilizza l'approccio walk the thread group precedentemente descritto.

for (Thread t : ThreadUtils.getAllThreads()) {
      System.out.println(t.getName() + ", " + t.isDaemon());
}
 1
Author: gerardw, 2018-04-11 11:25:56