Ist es möglich, das Ctrl+ C-Signal in einer Java-Befehlszeilenanwendung abzufangen? Ich möchte einige Ressourcen bereinigen, bevor ich das Programm beende.
Antworten:
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.
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.
kill -HUP
ist der "weichste" Kill von Unix und sollte den Shutdown-Hook ausführen. Ich bin mir nicht sicher über die Standardeinstellung kill
.
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();
}
}
});