Ctrl + C in Java abfangen

79

Ist es möglich, das Ctrl+ C-Signal in einer Java-Befehlszeilenanwendung abzufangen? Ich möchte einige Ressourcen bereinigen, bevor ich das Programm beende.

Pierre
quelle

Antworten:

87

Sie können der VM einen Shutdown-Hook hinzufügen, der ausgeführt wird, wenn die VM heruntergefahren wird:

Die Java Virtual Machine wird als Reaktion auf zwei Arten von Ereignissen heruntergefahren:

  • Das Programm wird normal beendet, wenn der letzte Nicht-Daemon-Thread beendet wird oder wenn die Methode exit (entsprechend System.exit) aufgerufen wird, oder

  • Die virtuelle Maschine wird als Reaktion auf einen Benutzerinterrupt wie die Eingabe von Ctrl+ Coder ein systemweites Ereignis wie die Benutzerabmeldung oder das Herunterfahren des Systems beendet.

Der Thread, den Sie als Shutdown-Hook übergeben, muss jedoch mehreren Regeln folgen. Lesen Sie daher die verknüpfte Dokumentation sorgfältig durch, um Probleme zu vermeiden. Dies beinhaltet die Gewährleistung der Gewindesicherheit, die schnelle Beendigung des Gewindes usw.

Wie Kommentator Jesper betont, werden Shutdown-Hooks beim normalen Herunterfahren der VM garantiert ausgeführt, aber wenn der VM-Prozess zwangsweise beendet wird, tun sie dies nicht. Dies kann passieren, wenn nativer Code fehlerhaft ist oder wenn Sie den Prozess ( kill -9, taskkill /f) zwangsweise beenden .

Aber in diesen Szenarien sind sowieso alle Wetten geschlossen, sodass ich nicht zu viel darüber nachdenken würde.

Joey
quelle
1
Beachten Sie, dass Shutdown-Hooks nicht unter allen Umständen garantiert funktionieren. Es kann Situationen geben, in denen sie nicht ausgeführt werden. Machen Sie die ordnungsgemäße Funktion Ihres Programms daher nicht davon abhängig, was Sie in einem Shutdown-Hook tun.
Jesper
4
Sie werden nicht ausgeführt, wenn der Prozess zwangsweise beendet wird ( TerminateProcess()oder SIGKILL), dies jedoch außerhalb des normalen Betriebs liegt. Da Strg + C bereits vom Shutdown-Hook abgedeckt ist, kann er sicher verwendet werden. Sie können nicht viel tun, wenn das Betriebssystem Ihren Prozess tatsächlich beendet.
Joey
1
kill -HUPist der "weichste" Kill von Unix und sollte den Shutdown-Hook ausführen. Ich bin mir nicht sicher über die Standardeinstellung kill.
livefree75
1
Standardmäßig wird der Shutdown-Hook auf meinem Computer ausgeführt (Redhat 7.3). Kill -9 nicht.
MikeKulls
2
Es wird nicht garantiert, dass Shutdown-Hooks in einer bestimmten Reihenfolge ausgeführt werden. Wenn Ihr Shutdown-Hook also von anderen Shutdown-Hooks abhängt, die noch nicht ausgeführt werden (oder umgekehrt), können Probleme auftreten.
Luke Hutchison
27

Nur für schnelle Konsolentestzwecke ...

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();
            }
        }
    });
bkomac
quelle