Можно ли поймать сигнал Ctrl+ Cв приложении командной строки java? Я хочу очистить некоторые ресурсы перед завершением программы.
Можно ли поймать сигнал Ctrl+ Cв приложении командной строки java? Я хочу очистить некоторые ресурсы перед завершением программы.
Вы можете подключить к виртуальной машине ловушку отключения, которая запускается всякий раз, когда виртуальная машина закрывается:
Виртуальная машина Java выключается в ответ на два типа событий:
Программа завершается нормально, когда завершается последний поток, не являющийся демоном, или когда вызывается метод exit (эквивалентно System.exit), или
Виртуальная машина прекращает работу в ответ на прерывание пользователя, такое как ввод Ctrl+ C, или общесистемное событие, такое как выход пользователя из системы или завершение работы системы.
Тем не менее, поток, который вы передаете в качестве обработчика выключения, должен следовать нескольким правилам, поэтому внимательно прочитайте связанную документацию, чтобы избежать каких-либо проблем. Это включает обеспечение безопасности потока, быстрое завершение потока и т. Д.
Кроме того, как отмечает комментатор Джеспер, хуки завершения работы гарантированно запускаются при нормальном завершении работы виртуальной машины, но если процесс виртуальной машины завершается принудительно, они этого не делают. Это может произойти, если собственный код ошибается или если вы принудительно завершаете процесс ( kill -9
,taskkill /f
).
Но в этих сценариях все ставки в любом случае отключены, поэтому я бы не стал тратить на это слишком много внимания.
TerminateProcess()
илиSIGKILL
), но это выходит за рамки нормальной работы, и поскольку Ctrl + C уже охвачен ловушкой выключения, его можно безопасно использовать. Вы ничего не сможете сделать, если ОС все равно завершит ваш процесс.kill -HUP
это самое «мягкое» уничтожение из Unix, и оно должно запускать ловушку выключения. Не уверен насчет дефолтаkill
.Просто для быстрого тестирования консоли ...
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(); } } });
источник
Верхний ответ предлагает использовать крючок отключения. Крючки отключения доставляют гораздо больше хлопот, чем они того стоят. Они работают в неопределенном порядке, и библиотеки, от которых вы зависите, могут добавлять свои собственные хуки выключения, что может означать, что кое-что, от чего зависит ваша собственная ловушка выключения, может быть деинициализировано до того, как будет запущена ваша ловушка завершения. Избавьте себя от головной боли и воспользуйтесь обработчиком сигналов:
Signal.handle(new Signal("INT"), // SIGINT signal -> System.out.println("Interrupted by Ctrl+C"));
Signal
в настоящее времяsun.misc.Signal
, что означает, что он будет устаревшим, но то, чем он заменяется, в настоящее время названjdk.internal.misc.Signal
, поэтому, пока команда Java не выяснит, как публично раскрыть обработчики сигналов не внутренним способом, будьте осторожны, чтобы этот вызов мог исчезнуть. Однако на данный момент (начиная с JDK 11)sun.misc.Signal
все еще существует.источник