web-dev-qa-db-fra.com

Obtenir une liste de tous les threads en cours d'exécution en Java

Est-il possible d'obtenir une liste de tous les threads en cours d'exécution dans la JVM actuelle (y compris les threads non démarrés par ma classe)? 

Est-il également possible d'obtenir les objets Thread et Class de tous les Thread de la liste?

Je veux être capable de faire cela avec du code.

201
Kryten

Pour obtenir un ensemble itérable:

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

Obtenez un handle vers la racine ThreadGroup, comme ceci:

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

Maintenant, appelez la fonction enumerate() sur le groupe racine à plusieurs reprises. Le second argument vous permet d'obtenir tous les threads, de manière récursive:

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

Notez comment nous appelons enumerate () à plusieurs reprises jusqu'à ce que le tableau soit suffisamment grand pour contenir toutes les entrées.

66
Frerich Raabe

Oui, jetez un oeil à obtenir une liste de discussions . Beaucoup d'exemples sur cette page.

C'est pour le faire par programme. Si vous voulez juste une liste sur Linux au moins, vous pouvez simplement utiliser cette commande:

kill -3 processid

et le VM fera un dump de thread sur stdout.

26
cletus

Vous pouvez obtenir beaucoup d'informations sur les threads à partir de ThreadMXBean .

Appelez la méthode statique ManagementFactory.getThreadMXBean () pour obtenir une référence au MBean.

17
Dan Dyer

Avez-vous jeté un œil à jconsole ?

Cela listera tous les threads en cours d'exécution pour un processus Java particulier.

Vous pouvez lancer jconsole à partir du dossier JDK bin.

Vous pouvez également obtenir une trace complète de la pile pour tous les threads en cliquant sur Ctrl+Break sous Windows ou en envoyant kill pid --QUIT sous Linux.

11
pjp

Dans Groovy vous pouvez appeler des méthodes privées

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

Dans Java , vous pouvez appeler cette méthode à l'aide de la réflexion, à condition que le gestionnaire de sécurité le permette.

5
Jarek Przygódzki

Vous pouvez essayer quelque chose comme ça:

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

et vous pouvez évidemment obtenir plus de caractéristiques de fil si vous en avez besoin.

4
hasskell

Extrait de code permettant d'obtenir la liste des threads démarrés par le thread principal:

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

sortie:

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

Si vous avez besoin de tous les threads, y compris les threads système, qui n'ont pas été démarrés par votre programme, supprimez la condition ci-dessous.

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

Maintenant sortie:

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
Ravindra babu

Dans la console Java, appuyez sur Ctrl-Break . Il listera tous les threads plus quelques informations sur le tas. Cela ne vous donnera évidemment pas accès aux objets. Mais cela peut quand même être très utile pour le débogage.

3
raoulsson

Les utilisateurs d’Apache Commons peuvent utiliser ThreadUtils . L'implémentation actuelle utilise l'approche de groupe de discussion décrite précédemment.

for (Thread t : ThreadUtils.getAllThreads()) {
      System.out.println(t.getName() + ", " + t.isDaemon());
}
3
gerardw
    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 + "  ");
        }
    }
3
ZZ Coder
0
Martin Kersten

Pour obtenir la liste des threads et de leurs états complets à l'aide de terminal, vous pouvez utiliser la commande ci-dessous:

jstack -l <PID>

Quel PID est l'id du processus en cours d'exécution sur l'ordinateur. Pour obtenir l'ID de processus de votre processus Java, vous pouvez simplement exécuter la commande ci-dessous:

jsp

Vous pouvez également analyser le vidage de threads généré par jstack dans des TDA (analyseurs de vidage de threads) tels que fastthread ou outil d'analyse de thread Spotify .

0
Amir Forsati