Автор оригинала: Pankaj Kumar.
Крючок выключения Java удобен для запуска некоторого кода при выходе из программы. Мы можем использовать java.lang.Runtime.addShutdownHook(Поток t)
метод для добавления крючка выключения в JVM.
Крюк выключения Java
Крюк завершения работы Java выполняется в этих двух случаях.
- Программа завершается нормально, или мы вызываем
System.exit()
метод для завершения программы. Подробнее о Системном классе Java . - Прерывания пользователя, такие как Ctrl+C, выключение системы и т.д.
Важными моментами в крюке завершения работы Java являются;
- Мы можем добавить несколько крючков выключения с помощью метода Runtime
addShutdownHook ()
. - Крючки выключения инициализируются, но не запускаются потоки . Они запускаются при срабатывании JVM выключения.
- Мы не можем определить порядок, в котором будут выполняться крючки завершения работы, как и при выполнении нескольких потоков.
- Все не вызываемые завершители выполняются, если завершение при выходе включено.
- Нет никакой гарантии, что крючки завершения работы будут выполняться, например, сбой системы, команда “Убить” и т. Д. Поэтому вы должны использовать его только для критических сценариев, таких как обеспечение высвобождения критических ресурсов и т.д.
- Вы можете удалить крюк, используя
Runtime.getRuntime().removeShutdownHook(крюк)
метод. - Как только крючки выключения запущены, их невозможно удалить. Вы получите
Исключение IllegalStateException
. - Вы получите исключение SecurityException, если менеджер безопасности присутствует и он запрещает
Выполнение("Выключение")
.
Пример крючка выключения Java
Итак, давайте рассмотрим пример отключения в java. Вот простая программа, в которой я строчно читаю файл из какого-то каталога и обрабатываю его. У меня состояние программы сохраняется в статической переменной, чтобы крюк выключения мог получить к ней доступ.
package com.journaldev.shutdownhook; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FilenameFilter; import java.io.IOException; public class FilesProcessor { public static String status = "STOPPED"; public static String fileName = ""; public static void main(String[] args) { String directory = "/Users/pankaj/temp"; Runtime.getRuntime().addShutdownHook(new ProcessorHook()); File dir = new File(directory); File[] txtFiles = dir.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { if (name.endsWith(".txt")) return true; else return false; } }); for (File file : txtFiles) { System.out.println(file.getName()); BufferedReader reader = null; status = "STARTED"; fileName = file.getName(); try { FileReader fr = new FileReader(file); reader = new BufferedReader(fr); String line; line = reader.readLine(); while (line != null) { System.out.println(line); Thread.sleep(1000); // assuming it takes 1 second to process each record // read next line line = reader.readLine(); } status = "PROCESSED"; } catch (IOException | InterruptedException e) { status = "ERROR"; e.printStackTrace(); }finally{ try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } status="FINISHED"; } }
Наиболее важной частью приведенного выше кода является строка № 16, где мы добавляем крюк выключения, ниже приведен класс реализации.
package com.journaldev.shutdownhook; public class ProcessorHook extends Thread { @Override public void run(){ System.out.println("Status="+FilesProcessor.status); System.out.println("FileName="+FilesProcessor.fileName); if(!FilesProcessor.status.equals("FINISHED")){ System.out.println("Seems some error, sending alert"); } } }
Это очень простое использование, я просто регистрирую состояние, когда начался крючок выключения, и если он еще не был завершен, то отправьте предупреждение (на самом деле это не так, его просто регистрируют здесь).
Давайте посмотрим, как некоторые программы выполняются через терминал.
- Программа завершается с помощью команды Ctrl+C.
Как вы можете видеть на приведенном выше изображении, крюк выключения начал выполняться, как только мы попытались убить JVM с помощью команды Ctrl+C.
- Программа выполняется нормально.
Обратите внимание, что хук вызывается и в случае обычного выхода, и он имеет статус печати как завершенный.
- Команда Kill для завершения JVM.
Я использовал два терминальных окна для запуска команды kill в программу java, поэтому операционная система завершила работу JVM, и в этом случае крюк выключения не был выполнен.
Это все для крючка выключения в java, я надеюсь, вы узнали о крючках выключения JVM и, возможно, найдете для этого применение.
Ссылка: API Doc