En Java, si un thread A crée et lance un thread B, le thread A ne pourra se terminer que lorsque le thread B aura aussi terminé son exécution.
Dans l'exemple suivant, le thread parent (classe Pricipale) crée et lance le thread enfant (une instance de la classe Secondaire).
public class Principale {
public static void main(String args[]) {
Thread t = new Thread(new Secondaire());
t.start();
for (int i = 0; i < 10; i++) {
System.out.print("1 ");
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
System.out.println("Fin");
}
}
class Secondaire implements Runnable {
public void run() {
while (true) {
System.out.print("2 ");
try {
Thread.sleep(300);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
}
Le problème dans ce programme est que le thread enfant poursuit son exécution, même après la fin du thread parent.
C:\>java Principale 1 2 2 1 2 2 1 2 1 2 2 1 2 2 1 2 1 2 2 1 2 2 1 2 1 2 2 Fin 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2...
Bien que ce comportement par défaut puisse être souhaitable dans certaines circonstances, il ne l'est pas toujours et c'est pourquoi il existe un moyen simple de changer ce comportement : les threads "démons".
Un thread démon est tout simplement un thread qui s'arrête automatiquement lorsque le thread qui l'a créé se termine. Dans l'exemple précédent, il suffit d'insérer un appel à la méthode setDaemon juste avant le démarrage du thread enfant.
Thread t = new Thread(new Secondaire()); t.setDaemon(true); // t s'arrêtera à la fin du thread parent t.start();
Ce qui donne cette fois le résultat voulu.
C:\>java Principale 1 2 2 1 2 2 1 2 1 2 2 1 2 2 1 2 1 2 2 1 2 2 1 2 1 2 2 Fin C:\>