Le langage Java fournit un mécanisme de regroupement des threads. Les unités d'exécution regroupées peuvent ainsi être manipulées plus facilement par l'intermédaire d'un seul objet appelé ThreadGroup.
Plutôt que d'appeler une méthode d'interruption ou de destruction pour chaque threads, l'appel d'une seule méthode interrupt() ou destroy() dans ces cas serait nécessaire pour appliquer à un ensemble de threads une opération particulière.
Le système d'exécution place un thread à l'intérieur d'un groupe de threads durant sa construction. Lors de la création d'un thread, il est possbible soit d'autoriser le système d'exécution à mettre le nouveau thread dans un groupe de threads par défaut adéquat, soit de créer explicitement un nouveau groupe de threads. L'unité d'exécution est un membre permanent du groupe de threads qu'il rejoint lors de sa création. Il n'est pas possible de déplacer un thread vers un nouveau groupe après que le thread ait été créé.
Lorsqu'une application Java démarre, le système d'exécution crée un objet ThreadGroup dénommé main. Dans le cas des applets Java, le nom du groupe de threads sera différent. Ainsi, tous les threads créés à l'intérieur du thread principal (main ou autre) deviennent, par défaut des membres de ce groupe de threads.
public class GroupeDefaut extends Thread { private static int n = 0; //nombre d'applications lancées public GroupeDefaut () { n++; System.out.println("Le groupe de threads parent : " + Thread.currentThread().getThreadGroup().getName() + " [" + Thread.currentThread().getName() + "-" + n + "]" ); } public void run() { System.out.println("Le groupe de threads parent : " + Thread.currentThread().getThreadGroup().getName() + " [" + Thread.currentThread().getName() + "]"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); return; } } public static void main(String args[]) { System.out.println("Le groupe de threads par défaut : " + Thread.currentThread().getThreadGroup().toString()); // Création de 5 threads enfants for (int i=0; i < 5; i++) { Thread ue = new GroupeDefaut(); //Déclaration de threads démons if (i % 2 == 0) ue.setDaemon(true); //Démarrage des threads... ue.start(); } System.out.println("Nombre total de threads dans le groupe : " + Thread.currentThread().getThreadGroup().activeCount()); } } |
L'obtention de l'objet ThreadGroup d'appartenance au thread courant est possible en invoquant la méthode getThreadGroup().
ThreadGroup groupe = ue.getThreadGroup();
Lors de la création d'un nouveau thread, il est possible de spécifier son groupe d'appartenance dans un constructeur de la classe Thread, en spécifiant l'objet ThreadGroup désiré.
public class NouveauGroupeThread { public static void main(String[] args) { ThreadGroup groupe1 = new ThreadGroup("Nouveau groupe 1"); ThreadGroup groupe2 = new ThreadGroup("Nouveau groupe 2"); int i; System.out.println("Evolution des threads par groupes"); System.out.println("Représentation : Nombre de threads " + "dans les différents groupes et dans le groupe principal"); Classe obj = new Classe(); for (i = 0; i < 5; i++) { Thread ue; if (i == 0) ue = new Classe(); else if (i % 2 == 0) ue = new Thread(groupe1, obj, "L'unite d'execution " + i); else ue = new Thread(groupe2, obj, "L'unite d'execution " + i); ue.start(); System.out.println(ue.getThreadGroup() + " : " + ue.getThreadGroup().activeCount() + " " + Thread.activeCount()); } Thread[] liste = new Thread[i + 1]; Thread.currentThread().getThreadGroup().enumerate(liste); System.out.println(" Nom des threads (" + liste.length + ") dans le groupe principal"); for(i = 0; i < liste.length; i++){ System.out.println(" " + liste[i].getName()); } int nbGrp = Thread.currentThread().getThreadGroup().activeGroupCount(); ThreadGroup[] GroupesThreads = new ThreadGroup[nbGrp]; Thread.currentThread().getThreadGroup().enumerate(GroupesThreads); System.out.print(" Nombre total de threads actifs dans le groupe courant : " + Thread.currentThread().getThreadGroup().activeCount() + " Nombre total de threads dans le premier groupe : " + groupe1.activeCount() + " Nombre total de threads dans le second groupe : " + groupe2.activeCount() + " Nombre total de groupe de threads dans le groupe courant : " + Thread.currentThread().getThreadGroup().activeGroupCount() + " Nombre total de threads dans les groupes enfants du groupe courant :"); for(i = 0; i < GroupesThreads.length; i++){ System.out.print(" " + GroupesThreads[i].activeCount()); } } } // Classe étendant la classe Thread public class Classe extends Thread { public static int cpt; public Classe(){ cpt++; } public void run() { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); return; } } } |
Le décompte des threads actifs dans le groupe principal, reflète le nombre total de threads actifs dans tous les groupes, auquel s'ajoute le nombre des groupes créés. C'est-pourquoi dans cet exemple, l'expresssion Thread.currentThread().getThreadGroup().activeCount() comptabilise sept threads, en fait 5 threads utilisateurs, et 2 groupes de threads.