Интервьюер: Расскажите, что такое Hook thread и сценарии его применения?

Java
Интервьюер: Расскажите, что такое Hook thread и сценарии его применения?

Статья впервые опубликована из личного WeChat: Сяоха изучает Java

Адрес личного сайта:woohoo.exception.site/java-concur…

содержание

  • 1. Знакомство с крючковой нитью

  • 2. Сценарии применения и меры предосторожности при использовании крючковой резьбы

  • 3. Крюк-тред антиприложения перезапускает реальный бой

  • 4. Адрес исходного кода GitHub

  • V. Резюме

1. Знакомство с крючковой нитью

Как правило, мы можем внедрить в приложение один или несколько потоков Hook (хуков), чтобы вКогда программа собирается выйти, то есть когда программа JVM вот-вот выйдет, поток Hook будет запущен и выполнен..

Давайте сначала посмотрим на пример кода:

示例代码
образец кода

  • : внедрить поток-ловушку в приложение, и в потоке распечатываются соответствующие журналы, включая журналы выполнения и выхода;
  • : снова внедрить поток-ловушку с той же логикой;
  • : выполнение основного потока завершается, и журнал печатается;

Запустите этот код, чтобы проверить:

Hook 线程执行结果
Результат выполнения потока хука

Из журнала печати видно, что когда выполнение основного потока заканчивается, то есть когда процесс JVM вот-вот завершится, запускаются два внедренных потока Hook и печатаются соответствующие журналы.

2. Сценарии применения и меры предосторожности при использовании крючковой резьбы

2.1 Сценарий применения

Как мы уже знаем выше, поток Hook может быть запущен и выполнен при выходе из программы JVM, так что же мы можем сделать с этой функцией?

Перечислите некоторые распространенные сценарии применения:

  1. Предотвращение повторения программы, конкретная реализация может проверить, был ли сгенерирован файл блокировки при запуске программы.Если он был сгенерирован, выйти из программы, если нет, сгенерировать файл блокировки, программа выполняется нормально и, наконец, внедрить поток Hook, так что когда JVM выходит, а затем удалить файл блокировки в потоке;

流程图
блок-схема

PS: Эта стратегия предотвращения повторного запуска программ также применяется к серверу Mysql, zookeeper, kafka и другим системам.

  1. Потоки-ловушки также могут выполнять некоторыеРелиз ресурсаоперации, такие как закрытие соединений с базой данных, соединений сокетов и т. д.

2.2 Примечания

  1. Поток Hook может быть выполнен правильно только тогда, когда он правильно получает сигнал выхода, если вы передаетеkill -9Таким образом, процесс принудительно завершается, извините, процесс не будет выполнять поток Hook, почему? Вы думаете, его заставили убить себя, как им могут управлять другие?
  2. Пожалуйста, не выполняйте какие-либо трудоемкие операции в потоке 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Создается ли файл:

lock 文件
заблокировать файл

Файл успешно сгенерирован. Далее запустим программу еще раз, чтобы проверить, можно ли ее запускать повторно:

重复启动程序,抛出异常
Многократный запуск программы, выбрасывание исключения

Как видите, программа не может запускаться повторно и выдаетThe program already running.исключение времени выполнения. Далее, поkill pidилиkill -l pidкоманда для завершения процесса:

Hook 线程被启动了
Крючковая нить начата

Когда программа собирается выйти, она запускает поток Hook, посмотрите на следующий.lockБыл ли удален файл:

.lock 文件被删除了
.lock файл был удален

На этом фактическая часть кода потока Hook закончена.

4. Адрес исходного кода GitHub

GitHub.com/для моей любви/…

V. Резюме

В этой статье мы узнали, что такое Hook thread, связанные с ним сценарии применения и меры предосторожности. Удачной учебы!

6. Ссылка

  • «Подробное объяснение программирования с высокой степенью параллелизма на Java»

7. Подарок | Интервью и учебные ресурсы по социальному обеспечению

Недавно я нашел в Интернете хороший ресурс в формате PDF «Java Core Interview Knowledge.pdf», чтобы поделиться с вами не только интервью, но и изучением, вы все стоит того! ! !

Как получить: Подпишитесь на официальный аккаунт:Сяоха изучает Java, закулисный ответресурс, вы можете получить ссылку на ресурс, это каталог и несколько скриншотов:

福利资源截图
Скриншот ресурсов социального обеспечения

福利资源截图
Скриншот ресурсов социального обеспечения

福利资源截图
Скриншот ресурсов социального обеспечения

福利资源截图
Скриншот ресурсов социального обеспечения

福利资源截图
Скриншот ресурсов социального обеспечения

福利资源截图
Скриншот ресурсов социального обеспечения

福利资源截图
Скриншот ресурсов социального обеспечения

Важные вещи говорятся дважды, как это получить: Подпишитесь на официальный аккаунт:Сяоха изучает Java, закулисный ответресурс, как за ссылки на ресурсы! ! !

Добро пожаловать в публичный аккаунт WeChat: Сяоха изучает Java

小哈学Java
Сяоха изучает Java