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:\>