2009-08-24 16 views

risposta

251

per ottenere un set di iterabile:

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

per convertirlo in un array:

Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]); 
+15

Sebbene molto più pulito rispetto all'altra alternativa proposta, questo ha lo svantaggio di incorrere nel costo di ottenere tracce di stack per tutti i thread. Se userete comunque quelle tracce dello stack, questo è chiaramente superiore. In caso contrario, questo potrebbe essere significativamente più lento per nessun guadagno oltre al codice pulito. – Eddie

+25

@Eddie È un'ipotesi dal senso comune o hai fatto esperimenti? "significativamente più lento" dici; quanto più lento? Ne vale la pena? Mi interrogo su ogni tentativo di peggiorare il codice per motivi di efficienza. Se hai un requisito di efficienza _e_ un'infrastruttura per misurare quantitativamente l'efficienza, allora sto bene con le persone che stanno peggiorando il codice, perché sembrano sapere cosa stanno facendo. Vedi [la radice di tutti i mali] (http: //en.wikipedia.org/wiki/Program_optimization # When_to_optimize) secondo Donald Knuth. – thejoshwolfe

+18

Non ho cronometrato queste alternative specifiche, ma ho lavorato con altri mezzi Java per raccogliere tracce di stack vs solo un elenco di thread. L'impatto sulle prestazioni sembra dipendere molto fortemente da quale JVM stai usando (JRockit vs Sun JVM per esempio). Vale la pena misurare nell'istanza specifica. Che ti influenzino o meno dipende dalla tua scelta JVM e dal numero di thread che hai. Ho scoperto che ottenere tutte le tracce dello stack tramite ThreadMXBean.dumpAllThreads per circa 250 thread richiedeva 150 - 200 msec mentre ottenevo solo l'elenco di thread (senza tracce) per non essere misurabile (0 msec). – Eddie

24

Sì, dai un'occhiata a getting a list of threads. Un sacco di esempi su quella pagina.

Ecco come fare a livello di programmazione. Se si desidera solo un elenco su Linux, almeno si può semplicemente utilizzare questo comando:

kill -3 processid 

e la VM farà una discarica filo sullo standard output.

+5

uccidere -3? Almeno sul mio linux, questo è "terminale chiuso". Uccide, non elenca. – khedron

+5

il cletus è effettivamente corretto - un kill -3 farà il dump allo stdout, indipendentemente da ciò che il segnale dovrebbe significare. Vorrei prendere in considerazione l'utilizzo di jstack, invece. –

10

Hai dato un'occhiata a jconsole?

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

È possibile avviare jconsole dalla cartella bin JDK.

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

+0

Voglio accedere alla lista all'interno della mia classe java – Kryten

+0

In tal caso, guarda la risposta di cletus. – pjp

+3

Ehm, perché la gente vota questo quando il ragazzo ha detto che voleva una soluzione programmatica? – cletus

62

ottenere un handle al ThreadGroup radice, in questo modo:

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

Ora, chiamare la funzione enumerate() sul gruppo radice più volte. Il secondo argomento consente di ottenere tutte le discussioni, in modo ricorsivo:

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

Si noti come chiamiamo enumerare() fino a quando la matrice è sufficientemente grande da contenere tutte le voci.

+19

Sono scioccato dal fatto che questa strategia sia così popolare su Internet. [La mia strategia] (http://stackoverflow.com/questions/1323408/get-a-list-of-all-threads-currently-running-in-java/3018672#3018672) è molto più semplice (1 riga di codice) e funziona altrettanto bene con il vantaggio aggiuntivo di evitare le condizioni di gara. – thejoshwolfe

+9

@thejoshwolfe: In realtà, sono d'accordo - penso che la tua risposta sia molto migliore, e probabilmente sarebbe stata la risposta accettata in primo luogo se non sarebbe stato un anno in ritardo. Se l'OP frequenta ancora SO, cosa che apparentemente fa, sarebbe ben consigliato di non accettare la mia risposta e piuttosto accettare la tua. –

+3

@thejoshwolfe la tua risulzione non funzionerà con java 1.4 – fnobbi

3

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.

14

È possibile ottenere molte informazioni sui thread dallo ThreadMXBean.

Chiamare il metodo statico ManagementFactory.getThreadMXBean() per ottenere un riferimento all'MBean.

+1

Mi piace questo. Sembra il metodo più pulito e più supportato dall'API –

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

In Groovy è possibile chiamare i metodi privati ​​

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

Nel Java, è possibile richiamare tale metodo utilizzando la reflection a condizione che il responsabile della sicurezza lo consenta.

2

Si può provare qualcosa di simile:

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

e ovviamente è possibile ottenere più filo caratteristica se avete bisogno.

1

Snippet di codice per ottenere l'elenco degli articoli di 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 avete bisogno di tutte le discussioni tra le discussioni di sistema, che non sono state iniziate da programma, rimuovere sotto condizione.

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

Ora d'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 
Problemi correlati