enfin bloquer dans le fil de démon

Je sais que finalement les blocs dans les threads de démon ne seront pas exécutés. Mais ma nature méticuleuse essaie de comprendre pourquoi et ce qui se passe dans la machine virtuelle Java si spéciale qu’elle ne peut pas appeler le code sous ce bloc.

Je pense qu’il est en quelque sorte lié à la stack d’appel qu’il ne faut pas se détendre, mais ne sait pas comment. Quelqu’un peut-il s’il vous plaît faire la lumière sur ce sujet. Merci.

Qui a dit que les blocs des démons ne s’exécutent pas? Ce n’est pas vrai en général.

Vous avez peut- être entendu dire que l’exécution d’un bloc finally n’est pas garantie lorsqu’une machine virtuelle Java est arrêtée pendant l’exécution du bloc try (ou catch ). C’est correct (et cela peut facilement arriver aux threads de démon).

Mais encore une fois: lors du fonctionnement normal, rien n’empêche finally blocs de s’exécuter normalement dans les threads de démon: ils ne sont pas gérés différemment.

Le problème d’arrêt est simple: lorsque la machine virtuelle Java est invitée à s’arrêter ou même d’être forcée de s’éteindre, elle risque de ne plus pouvoir exécuter d’autres instructions.

Par exemple, sur les systèmes d’exploitation POSIX-y, le signal 9 (SIGKILL) force une application à s’arrêter, ce qui ne lui laisse aucune possibilité de nettoyage (c’est pourquoi le signal 15 (SIGTERM) est généralement préféré). Dans ce cas, la machine virtuelle Java ne peut pas exécuter le bloc finally , car le système d’exploitation ne la laissera plus fonctionner.

Si la machine virtuelle Java se ferme pendant l’exécution du code try ou catch, le bloc finally peut ne pas s’exécuter.
Arrêt normal – cela se produit lorsque le dernier thread non démon se termine ou lorsque Runtime.exit ()
Lorsqu’un thread se ferme, la machine virtuelle Java crée un inventaire des threads en cours d’exécution. Si les seuls threads restant sont des threads démon, elle déclenche un arrêt ordonné. Lorsque la machine virtuelle Java s’arrête, tous les threads de démon restants sont abandonnés. Enfin, les blocs ne sont pas exécutés, les stacks ne sont pas déroulées, la machine virtuelle Java vient de quitter. Les threads Daemon doivent être utilisés avec parcimonie. Peu d’activités de traitement peuvent être abandonnées en toute sécurité à tout moment sans nettoyage. En particulier, il est dangereux d’utiliser des threads de démon pour les tâches susceptibles d’exécuter toute sorte d’E / S. Les threads de démon sont mieux sauvegardés pour les tâches de “maintenance”, tels qu’un thread d’arrière-plan qui supprime périodiquement les entrées expirées d’un cache en mémoire.

Dernier exemple de thread non démon:

 public class TestDaemon { private static Runnable runnable = new Runnable() { @Override public void run() { try { while (true) { System.out.println("Is alive"); Thread.sleep(10); // throw new RuntimeException(); } } catch (Throwable t) { t.printStackTrace(); } finally { System.out.println("This will never be executed."); } } }; public static void main(Ssortingng[] args) throws InterruptedException { Thread daemon = new Thread(runnable); daemon.setDaemon(true); daemon.start(); Thread.sleep(100); // daemon.stop(); System.out.println("Last non-daemon thread exits."); } } 

Sortie:

 Is alive Is alive Is alive Is alive Is alive Is alive Is alive Is alive Is alive Is alive Last non-daemon thread exits. Is alive Is alive Is alive Is alive Is alive 

J’ai créé deux threads non-démons qui se termineront avant les deux threads restants du démon.

Un thread non-démon attend 20 secondes, un démon attend 40 secondes, un thread non-démon en veille pendant 15 secondes, un thread démon en veille pendant 30 secondes, un thread démon en veille pendant 10 secondes. L’idée de terminer les threads non-démons avant certains démons.

Comme le résultat le suggère, la machine virtuelle Java s’arrête dès qu’il n’y a plus de thread non démon en vie, sans exécuter les instructions restantes dans les tâches runnables des threads démons, même si elles se trouvent à l’intérieur du bloc sans avoir généré d’exception InterruptedException.

 public class DeamonTest { public static void main(Ssortingng[] args) { spawn(40000, Action.wait, true); spawn(30000, Action.sleep, true); spawn(10000, Action.sleep, true); spawn(20000, Action.wait, false); spawn(15000, Action.sleep, false); } enum Action { wait, sleep } private static void spawn(final long time, final Action action, boolean daemon) { final Thread thread = new Thread(new Runnable() { @Override public void run() { Thread thread = Thread.currentThread(); try { switch (action) { case wait: { synchronized (this) { System.out.println(thread + " daemon=" + thread.isDaemon() + ": waiting"); wait(time); } break; } case sleep: { System.out.println(thread + " daemon=" + thread.isDaemon() + ": sleeping"); Thread.sleep(time); } } System.out.println(thread + " daemon=" + thread.isDaemon() + ": exiting"); } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println(thread + " daemon=" + thread.isDaemon() + ": finally exiting"); } } }); thread.setDaemon(daemon); thread.start(); } }