Un bloc final est-il toujours exécuté?

Y a-t-il des conditions dans lesquelles java pourrait ne pas fonctionner? Merci.

    des didacticiels Sun

    Remarque: Si la JVM se ferme pendant l’exécution du code try ou catch, le bloc finally peut ne pas s’exécuter. De même, si le thread exécutant le code try ou catch est interrompu ou tué, le bloc finally peut ne pas s’exécuter même si l’application dans son ensemble continue.

    Je ne connais pas d’autre moyen que le bloc final ne pourrait pas exécuter …

    System.exit arrête la machine virtuelle.

    Termine la machine virtuelle Java en cours d’exécution. L’argument sert de code d’état; par convention, un code de statut différent de zéro indique une terminaison anormale.

    Cette méthode appelle la méthode exit dans la classe Runtime . Cette méthode ne retourne jamais normalement.

      try { System.out.println("hello"); System.exit(0); } finally { System.out.println("bye"); } // try-finally 

    “bye” n’imprime pas dans le code ci-dessus.

    Juste pour développer ce que d’autres ont dit, tout ce qui ne cause pas quelque chose comme la sortie de la JVM entraînera le bloc final. Donc, la méthode suivante:

     public static int Stupid() { try { return 0; } finally { return 1; } } 

    va étrangement comstackr et retourner 1.

    En relation avec System.exit, il existe également certains types de pannes catastrophiques pour lesquelles un bloc finally peut ne pas s’exécuter. Si la JVM manque complètement de mémoire, il se peut qu’elle se ferme sans accroc ou qu’elle se produise.

    Plus précisément, je me souviens d’un projet où nous avons bêtement essayé d’utiliser

     catch (OutOfMemoryError oome) { // do stuff } 

    Cela n’a pas fonctionné car la JVM n’avait plus de mémoire pour exécuter le bloc catch.

     try { for (;;); } finally { System.err.println("?"); } 

    Dans ce cas le final ne s’exécutera pas (à moins que le Thread.stop obsolète soit appelé, ou un équivalent, par exemple, via une interface d’outils).

    Le tutoriel Sun a été cité à tort dans ce fil de discussion.

    Remarque: Si la JVM se ferme pendant l’exécution du code try ou catch, le bloc finally ne s’exécute pas. De même, si le thread exécutant le code try ou catch est interrompu ou tué, le bloc finally ne s’exécutera pas même si l’application dans son ensemble continue.

    Si vous examinez attentivement le tutoriel sun pour le bloquer, il ne dit pas “ne sera pas exécuté” mais “peut ne pas exécuter” Voici la description correcte

    Remarque: Si la JVM se ferme pendant l’exécution du code try ou catch, le bloc finally peut ne pas s’exécuter. De même, si le thread exécutant le code try ou catch est interrompu ou tué, le bloc finally peut ne pas s’exécuter même si l’application dans son ensemble continue.

    La raison apparente de ce comportement est que l’appel à system.exit () est traité dans un thread de système d’exécution, ce qui peut prendre du temps pour arrêter jvm, tandis que le planificateur de thread peut demander à s’exécuter. Donc, finalement, est conçu pour toujours être exécuté, mais si vous fermez jvm, il peut arriver que jvm se ferme avant d’être finalement exécuté.

    Aussi, si un blocage / livelock se produit à l’intérieur du bloc try .

    Voici le code qui le démontre:

     public class DeadLocker { private static class SampleRunnable implements Runnable { private Ssortingng threadId; private Object lock1; private Object lock2; public SampleRunnable(Ssortingng threadId, Object lock1, Object lock2) { super(); this.threadId = threadId; this.lock1 = lock1; this.lock2 = lock2; } @Override public void run() { try { synchronized (lock1) { System.out.println(threadId + " inside lock1"); Thread.sleep(1000); synchronized (lock2) { System.out.println(threadId + " inside lock2"); } } } catch (Exception e) { } finally { System.out.println("finally"); } } } public static void main(Ssortingng[] args) throws Exception { Object ob1 = new Object(); Object ob2 = new Object(); Thread t1 = new Thread(new SampleRunnable("t1", ob1, ob2)); Thread t2 = new Thread(new SampleRunnable("t2", ob2, ob1)); t1.start(); t2.start(); } } 

    Ce code produit la sortie suivante:

     t1 inside lock1 t2 inside lock1 

    et “finalement” ne s’imprime jamais

    Voici quelques conditions qui peuvent contourner un bloc finalement:

    1. Si la JVM se ferme pendant l’exécution du code try ou catch, le bloc finally peut ne pas s’exécuter.
    2. Arrêt normal – cela se produit lorsque le dernier thread non-démon quitte OU lorsque Runtime.exit ()
    3. Lorsqu’un thread se ferme, la JVM effectue un inventaire des threads en cours d’exécution et si les seuls threads restant sont des threads démons, il déclenche un arrêt ordonné. Lorsque la JVM s’arrête, tous les threads de démon restants sont abandonnés, alors les blocs ne sont pas exécutés, les stacks ne sont pas déroulées, la JVM se termine simplement. Les threads de démons doivent être utilisés avec parcimonie et peu d’activités de traitement peuvent être abandonnées en toute sécurité sans nettoyage. En particulier, il est dangereux d’utiliser des threads de démon pour des tâches susceptibles d’exécuter toute sorte d’E / S. Les threads de démon sont mieux enregistrés pour les tâches de “maintenance”, telles qu’un thread d’arrière-plan qui supprime régulièrement les entrées expirées d’un cache en mémoire.

    Le dernier thread non-démon quitte l’exemple:

     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 

    Je suis tombé sur un cas très spécifique du bloc Final qui n’exécutait pas spécifiquement le framework de lecture.

    J’ai été surpris de constater que le bloc finally de ce code d’action de contrôleur n’a été appelé qu’après une exception, mais jamais lorsque l’appel a réussi.

     try { InputStream is = getInputStreamMethod(); renderBinary(is, "out.zip"); catch (Exception e) { e.printStackTrace(); } finally { cleanUp(); } 

    Peut-être que le thread est terminé ou quelque chose lorsque renderBinary () est appelé. Je soupçonne que la même chose se produit pour les autres appels de render (), mais je ne l’ai pas vérifié.

    J’ai résolu le problème en déplaçant le renderBinary () après le try / catch. Une enquête plus approfondie a révélé que le jeu fournit une annotation @Finally pour créer une méthode qui est exécutée après l’exécution d’une action du contrôleur. La mise en garde est que cela sera appelé après l’exécution de toute action dans le contrôleur, donc ce n’est pas toujours un bon choix.

    Dans les cas suivants, finalement bloc ne sera pas exécuté: –

    • Lorsque System.exit(0) est appelé depuis le bloc try .
    • Lorsque JVM manque de mémoire
    • Lorsque votre processus Java est tué de force à partir de la tâche mgr ou de la console
    • Condition de blocage dans votre bloc try
    • Lorsque votre machine arrête une panne de courant

    Il peut également y avoir d’autres cas marginaux, où finalement bloc ne sera pas exécuté.

     //If ArithmeticException Occur Inner finally would not be executed class Temp { public static void main(Ssortingng[] s) { try { int x = 10/s.length; System.out.println(x); try { int z[] = new int[s.length]; z[10] = 1000; }catch(ArrayIndexOutOfBoundsException e) { System.out.println(e); } finally { System.out.println("Inner finally"); } } catch(ArithmeticException e) { System.out.println(e); } finally { System.out.println("Outer Finally"); } System.out.println("Remaining Code"); } } 

    En tant que débordement de la stack, les membres ont mentionné que le blocage final ne s’exécutera pas lorsque:

    1: JVM manque de mémoire

    2: le thread a été tué

    3: Lors de l’utilisation des blocs try, catch et finally nesteds, une exception ARITHMETIC EXCEPTION s’est produite, puis l’interne ne s’exécute pas

      class FinallyExecution{ public static void main(Ssortingng [] args){ try { int x = 5; System.out.println(x / 0); System.out.println("I wont even get executed"); try { Ssortingng p = null; System.out.println(p.length()); } catch (NullPointerException e) { System.out.println("Sorry you got a null in that ssortingng"); } finally { System.out.println("What am I doing here?");//this wont execute } } catch(ArithmeticException e){ System.out.println("You cannot divide by zero"); } finally{ System.out.println("I can execute now"); } } 

    }