109 votes

Attraper Ctrl+C en Java

Est-il possible d'attraper le Ctrl + C dans une application Java en ligne de commande ? J'aimerais nettoyer certaines ressources avant de terminer le programme.

0 votes

106voto

Joey Points 148544

Vous pouvez joindre un crochet d'arrêt à la VM qui s'exécute à chaque fois que la VM s'arrête :

La machine virtuelle Java s'arrête en réponse à deux types d'événements :

  • Le programme se termine normalement, lorsque le dernier thread non démon se termine ou lorsque la méthode exit (équivalente à System.exit) est invoquée, ou

  • La machine virtuelle est arrêtée en réponse à une interruption de l'utilisateur, par exemple en tapant Ctrl + C ou un événement touchant l'ensemble du système, tel que la déconnexion d'un utilisateur ou l'arrêt du système.

Le fil que vous passez en tant que crochet d'arrêt doit cependant respecter plusieurs règles, alors lisez attentivement la documentation liée pour éviter tout problème. Il s'agit notamment d'assurer la sécurité des threads, la terminaison rapide du thread, etc.

De plus, comme le souligne Jesper, les crochets d'arrêt sont garantis de s'exécuter lors de l'arrêt normal de la VM, mais pas si le processus de la VM est arrêté de force. Cela peut se produire si le code natif se plante ou si vous arrêtez le processus de force ( kill -9 , taskkill /f ).

Mais dans ces scénarios, tout est perdu de toute façon, et je ne m'y attarderais donc pas trop.

1 votes

Attention, l'exécution des crochets d'arrêt n'est pas garantie en toutes circonstances ; il peut y avoir des situations où ils ne sont pas exécutés, alors ne faites pas dépendre le bon fonctionnement de votre programme de ce que vous faites dans un crochet d'arrêt.

4 votes

Ils ne sont pas exécutés lorsque le processus est interrompu de force ( TerminateProcess() o SIGKILL ) mais c'est en dehors des opérations normales et comme Ctrl+C est déjà couvert par le crochet d'arrêt, il n'y a pas de danger à l'utiliser. De toute façon, vous ne pouvez pas faire grand-chose si le système d'exploitation met fin à votre processus.

0 votes

Si j'exécute kill (envoi d'un signal TERM), cela sera-t-il pris en compte dans le crochet d'arrêt ? (Notez que ce n'est pas la même chose que kill -9 (ce qui, d'après ce qui précède, signifie qu'il ne se coince pas dans le crochet).

52voto

bkomac Points 980

Juste pour tester rapidement la console...

Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            try {
                Thread.sleep(200);
                System.out.println("Shutting down ...");
                //some cleaning up code...

            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                e.printStackTrace();
            }
        }
    });

15voto

Luke Hutchison Points 3228

La première réponse suggère d'utiliser un crochet d'arrêt. Les crochets d'arrêt posent beaucoup plus de problèmes qu'ils n'en valent la peine. Ils s'exécutent dans un ordre indéterminé, et les bibliothèques dont vous dépendez peuvent ajouter leurs propres crochets d'arrêt, ce qui peut signifier que quelque chose dont dépend votre propre crochet d'arrêt peut être désinitialisé avant que votre crochet d'arrêt ne s'exécute. Epargnez-vous ce casse-tête et utilisez un gestionnaire de signal :

Signal.handle(new Signal("INT"),  // SIGINT
    signal -> System.out.println("Interrupted by Ctrl+C"));

Signal est actuellement sun.misc.Signal ce qui signifie qu'il sera déprécié -- mais ce par quoi il sera remplacé s'appelle actuellement jdk.internal.misc.Signal En attendant que l'équipe Java trouve un moyen d'exposer publiquement les gestionnaires de signaux d'une manière non interne, cet appel risque de disparaître. Pour l'instant (à partir du JDK 11), sun.misc.Signal existe toujours.

4voto

skaffman Points 197885

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X