Obtenez une liste de tous les Threads en cours D'exécution en Java
est-ce que je peux obtenir une liste de tous les Threads en cours d'exécution dans la JVM actuelle (y compris les Threads Non commencés par ma classe)?
est-il également possible d'obtenir le Thread et les objets de classe de tous les Thread dans la liste?
je veux pouvoir le faire à travers le code.
12 réponses
pour obtenir un ensemble itérable:
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
pour le convertir en tableau:
Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]);
obtenir une poignée à 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, récursivement:
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 assez grand pour contenir toutes les entrées.
Oui, jetez un oeil à obtenir une liste de threads . Beaucoup d'exemples sur cette page.
c'est à faire programmatiquement. Si vous voulez juste une liste sur Linux, au moins, vous pouvez simplement utiliser cette commande:
kill -3 processid
et la VM va faire un dump de thread à stdout.
vous pouvez obtenir beaucoup d'informations sur les fils de la ThreadMXBean .
Appel de la statique ManagementFactory.getthreadmxbean () méthode pour obtenir une référence au MBean.
avez-vous regardé jconsole ?
liste de tous les threads tournant pour un processus Java particulier.
vous pouvez lancer jconsole à partir du dossier bin JDK.
vous pouvez également obtenir une trace de pile complète pour tous les threads en appuyant sur Ctrl+Break
sous Windows ou en envoyant kill pid --QUIT
sous Linux.
Dans Groovy vous pouvez appeler les méthodes privées
// Get a snapshot of the list of all threads
Thread[] threads = Thread.getThreads()
dans Java , vous pouvez invoquer cette méthode en utilisant la réflexion à condition que le gestionnaire de sécurité l'autorise.
Dans la console java, cliquez sur Ctrl-Break . Il énumérera tous les fils plus quelques informations sur le tas. Cela ne vous donnera pas accès aux objets bien sûr. Mais cela peut être très utile pour déboguer de toute façon.
Vous pouvez essayer quelque chose comme ceci:
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éristique de fil si vous avez besoin.
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 + " ");
}
}
extrait de Code pour obtenir la liste des threads commencé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é lancé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
les utilisateurs D'Apache commons peuvent utiliser ThreadUtils. la mise en œuvre actuelle utilise l'approche du groupe walk the thread décrite précédemment.
for (Thread t : ThreadUtils.getAllThreads()) {
System.out.println(t.getName() + ", " + t.isDaemon());
}