Автор оригинала: 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