网站服务器租用价格怎么算,软件技术开发合同,wordpress和node.js,优化营商环境建议一、Hook 线程介绍通常情况下#xff0c;我们可以向应用程序注入一个或多个 Hook (钩子) 线程#xff0c;这样#xff0c;在程序即将退出的时候#xff0c;也就是 JVM 程序即将退出的时候#xff0c;Hook 线程就会被启动执行。先看一段示例代码#xff1a;①#xff1a;…一、Hook 线程介绍通常情况下我们可以向应用程序注入一个或多个 Hook (钩子) 线程这样在程序即将退出的时候也就是 JVM 程序即将退出的时候Hook 线程就会被启动执行。先看一段示例代码①为应用程序注入一个钩子(Hook)线程线程中打印了相关日志包括正在运行以及退出的日志②再次注入一个同样逻辑的钩子(Hook)线程③主线程执行结束打印日志运行这段代码来验证一下从打印日志看到当主线程执行结束也就是 JVM 进程即将退出的时候注入的两个 Hook 线程都被启动并打印相关日志。二、Hook 线程的应用场景注意事项2.1 应用场景上面我们已经知道了 Hook 线程能够在 JVM 程序退出的时候被启动且执行那么我们能够通过这种特性做点什么呢罗列一些常见应用场景防止程序重复执行具体实现可以在程序启动时校验是否已经生成 lock 文件如果已经生成则退出程序如果未生成则生成 lock 文件程序正常执行最后再注入 Hook 线程这样在 JVM 退出的时候线程中再将 lock 文件删除掉PS: 这种防止程序重复执行的策略也被应用于 Mysql 服务器zookeeper, kafka 等系统中。Hook 线程中也可以执行一些资源释放的操作比如关闭数据库连接Socket 连接等。2.2 注意事项Hook 线程只有在正确接收到退出信号时才能被正确执行如果你是通过 kill -9这种方式强制杀死的进程那么抱歉进程是不会去执行 Hook 线程的为什么呢你想啊它自己都被强制干掉了哪里还管的上别人呢请不要在 Hook 线程中执行一些耗时的操作这样会导致程序长时间不能退出。三、Hook 线程防应用重启实战针对上面防应用重启的场景利用 Hook 线程我们来实战一下贴上代码import java.io.File;import java.io.IOException;import java.util.concurrent.TimeUnit;/*** author 小泽java* date 2019/4/15* time 下午3: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 线程代码实战部分结束了。