Статья впервые опубликована из личного WeChat: Сяоха изучает Java
Адрес личного сайта:woohoo.exception.site/java-concur…
содержание
-
1. Знакомство с крючковой нитью
-
2. Сценарии применения и меры предосторожности при использовании крючковой резьбы
-
3. Крюк-тред антиприложения перезапускает реальный бой
-
4. Адрес исходного кода GitHub
-
V. Резюме
1. Знакомство с крючковой нитью
Как правило, мы можем внедрить в приложение один или несколько потоков Hook (хуков), чтобы вКогда программа собирается выйти, то есть когда программа JVM вот-вот выйдет, поток Hook будет запущен и выполнен..
Давайте сначала посмотрим на пример кода:
- ①: внедрить поток-ловушку в приложение, и в потоке распечатываются соответствующие журналы, включая журналы выполнения и выхода;
- ②: снова внедрить поток-ловушку с той же логикой;
- ③: выполнение основного потока завершается, и журнал печатается;
Запустите этот код, чтобы проверить:
Из журнала печати видно, что когда выполнение основного потока заканчивается, то есть когда процесс JVM вот-вот завершится, запускаются два внедренных потока Hook и печатаются соответствующие журналы.
2. Сценарии применения и меры предосторожности при использовании крючковой резьбы
2.1 Сценарий применения
Как мы уже знаем выше, поток Hook может быть запущен и выполнен при выходе из программы JVM, так что же мы можем сделать с этой функцией?
Перечислите некоторые распространенные сценарии применения:
- Предотвращение повторения программы, конкретная реализация может проверить, был ли сгенерирован файл блокировки при запуске программы.Если он был сгенерирован, выйти из программы, если нет, сгенерировать файл блокировки, программа выполняется нормально и, наконец, внедрить поток Hook, так что когда JVM выходит, а затем удалить файл блокировки в потоке;
PS: Эта стратегия предотвращения повторного запуска программ также применяется к серверу Mysql, zookeeper, kafka и другим системам.
- Потоки-ловушки также могут выполнять некоторыеРелиз ресурсаоперации, такие как закрытие соединений с базой данных, соединений сокетов и т. д.
2.2 Примечания
- Поток Hook может быть выполнен правильно только тогда, когда он правильно получает сигнал выхода, если вы передаете
kill -9
Таким образом, процесс принудительно завершается, извините, процесс не будет выполнять поток Hook, почему? Вы думаете, его заставили убить себя, как им могут управлять другие? - Пожалуйста, не выполняйте какие-либо трудоемкие операции в потоке Hook, которые могут привести к тому, что программа не сможет выйти в течение длительного времени.
3. Крюк-тред антиприложения перезапускает реальный бой
Для приведенного выше сценария предотвращения перезапуска приложения с помощью потока Hook давайте попробуем его и вставим код:
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
* @author 犬小哈(微信号: 小哈学Java)
* @date 2019/4/10
* @time 下午9:56
* @discription
**/
public class PreventDuplicated {
/** .lock 文件存放路径 */
private static final String LOCK_FILE_PATH = "./";
/** .lock 文件名称 */
private static final String LOCK_FILE_NAME = ".lock";
public static void main(String[] args) {
// 校验 .lock 文件是否已经存在
checkLockFile();
// 注入 Hook 线程
addShutdownHook();
// 模拟程序一直运行
for (;;) {
try {
TimeUnit.SECONDS.sleep(1);
System.out.println("The program is running ...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 注入 Hook 线程
*/
private static void addShutdownHook() {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
// 接受到了退出信号
System.out.println("The program received kill signal.");
// 删除 .lock 文件
deleteLockFile();
}));
}
/**
* 校验 .lock 文件是否已经存在
*/
private static void checkLockFile() {
if (isLockFileExisted()) {
// .lock 文件已存在, 抛出异常, 退出程序
throw new RuntimeException("The program already running.");
}
// 不存在,则创建 .lock 文件
createLockFile();
}
/**
* 创建 .lock 文件
*/
private static void createLockFile() {
File file = new File(LOCK_FILE_PATH + LOCK_FILE_NAME);
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* .lock 文件 是否存在
* @return
*/
private static boolean isLockFileExisted() {
File file = new File(LOCK_FILE_PATH + LOCK_FILE_NAME);
return file.exists();
}
/**
* 删除 .lock 文件
*/
private static void deleteLockFile() {
File file = new File(LOCK_FILE_PATH + LOCK_FILE_NAME);
file.delete();
}
}
Запустите программу, и вывод консоли будет следующим:
Программа запущена, давайте посмотрим.lock
Создается ли файл:
Файл успешно сгенерирован. Далее запустим программу еще раз, чтобы проверить, можно ли ее запускать повторно:
Как видите, программа не может запускаться повторно и выдаетThe program already running.
исключение времени выполнения. Далее, поkill pid
илиkill -l pid
команда для завершения процесса:
Когда программа собирается выйти, она запускает поток Hook, посмотрите на следующий.lock
Был ли удален файл:
На этом фактическая часть кода потока Hook закончена.
4. Адрес исходного кода GitHub
V. Резюме
В этой статье мы узнали, что такое Hook thread, связанные с ним сценарии применения и меры предосторожности. Удачной учебы!
6. Ссылка
- «Подробное объяснение программирования с высокой степенью параллелизма на Java»
7. Подарок | Интервью и учебные ресурсы по социальному обеспечению
Недавно я нашел в Интернете хороший ресурс в формате PDF «Java Core Interview Knowledge.pdf», чтобы поделиться с вами не только интервью, но и изучением, вы все стоит того! ! !
Как получить: Подпишитесь на официальный аккаунт:Сяоха изучает Java, закулисный ответресурс, вы можете получить ссылку на ресурс, это каталог и несколько скриншотов:
Важные вещи говорятся дважды, как это получить: Подпишитесь на официальный аккаунт:Сяоха изучает Java, закулисный ответресурс, как за ссылки на ресурсы! ! !