mysql 钩子_面试官: 什么是 Hook (钩子) 线程以及应用场景?

一、Hook 线程介绍

通常情况下,我们可以向应用程序注入一个或多个 Hook (钩子) 线程,这样,在程序即将退出的时候,也就是 JVM 程序即将退出的时候,Hook 线程就会被启动执行。

先看一段示例代码:

267c2105e9262a27fe8d08f71b0f1c2d.png

①:为应用程序注入一个钩子(Hook)线程,线程中,打印了相关日志,包括正在运行以及退出的日志;

②:再次注入一个同样逻辑的钩子(Hook)线程;

③:主线程执行结束,打印日志;

运行这段代码,来验证一下:

4269b637f7fa6042fd1b49b0c987aa6c.png

从打印日志看到,当主线程执行结束,也就是 JVM 进程即将退出的时候,注入的两个 Hook 线程都被启动并打印相关日志。

二、Hook 线程的应用场景&注意事项

2.1 应用场景

上面我们已经知道了, Hook 线程能够在 JVM 程序退出的时候被启动且执行,那么,我们能够通过这种特性,做点什么呢?

罗列一些常见应用场景:

防止程序重复执行,具体实现可以在程序启动时,校验是否已经生成 lock 文件,如果已经生成,则退出程序,如果未生成,则生成 lock 文件,程序正常执行,最后再注入 Hook 线程,这样在 JVM 退出的时候,线程中再将 lock 文件删除掉;

9bb2ad35f84bf7af5b0bd342b0093aa8.png

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();

}

}

运行程序,控制台输出如下:

9eed37a2d74c404793e81b0d4ed717a5.png

程序一直运行中,再来看下 .lock 文件是否生成:

b7e9684a00de5b6199333018e75302fb.png

文件生成成功,接下来,我们再次运行程序,看看是否能够重复启动:

8ab496aebabc27be03b4d737202e3013.png

可以看到,无法重复运行程序,且抛出了 The program already running. 的运行时异常。接下来,通过 kill pid 或者 kill -l pid 命令来结束进程:

c7a1b65292123e647f87815089bfc902.png

程序在即将退出的时候,启动了 Hook 线程,在看下 .lock 文件是否已被删除:

b951b849810fbed65ebae61dc5852f67.png

到此,Hook 线程代码实战部分结束了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/562049.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML+CSS+JS实现 ❤️H5 3D传送带视差照片特效❤️

效果演示: 代码目录: 主要代码实现: 部分CSS样式: html, body, .stage, .ring, .img {width: 100%;height: 100%;transform-style: preserve-3d;user-select: none; }html, body, .stage {overflow: hidden;background: #000; …

mysql慢查询日志轮转_MySQL slow log相关参数解释

slow_query_log1 #是否启用慢查询日志,1为启用,0为禁用slow_query_log_fileslow.log #指定慢查询日志文件的路径和名字,可使用绝对路径指定;默认值是主机名_slow.log,位于datadir目录long_query_time2 …

HTML+CSS+JS实现 ❤️h5酷炫的天体木星动画特效❤️

效果演示: 代码目录: 主要代码实现: 部分CSS样式: body {margin: 0;overflow: hidden;position: relative;width: 100vw;height: 100vh;background-image: url("../img/bg.jpg");background-size: cover; }canvas {d…

HTML+CSS+JS实现 ❤️彩色3D线条动画特效❤️

效果演示&#xff1a; 代码目录&#xff1a; 主要代码实现&#xff1a; HTML代码 : <!doctype html> <html><head><meta charset"utf-8"><title>彩带特效</title></head><body><script id"fs" type…

mysql column legnth too big for_Column length too big for column 'Flist' (max = 21845);

建表语句报如下错误&#xff1a;CREATE TABLE test_1 (Fid bigint(20) unsigned NOT NULL,Ftype tinyint(4) unsigned NOT NULL,Flist varchar(65532) DEFAULT NULL,Fstatus tinyint(3) unsigned DEFAULT 0,Ftime bigint unsigned DEFAULT 0,Faddtime bigint unsigned DEFAULT …

HTML+CSS+JS实现 ❤️卡通人物吃水果游戏❤️

效果演示&#xff1a; 代码目录&#xff1a; 主要代码实现&#xff1a; HTML代码 : <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial…

py哪个函数可以返回输入的变量类型_[Python基础]二、pycharm,python变量

2.1 Python简介Life is short,you need Python (人生苦短&#xff0c;我用Python)解释器&#xff1a;将其他语言翻译成机器语言的工具&#xff0c;称为编译器编译器的翻译方法有两种&#xff1a;编译解释Python的设计哲学优雅明确简单Python开发者哲学&#xff1a;用一种方法&a…

HTML+CSS+JS实现 贪吃蛇游戏源码

效果演示&#xff1a; 文末获取源码 代码目录&#xff1a; 主要代码实现&#xff1a; 部分代码 : <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv&qu…

mysql sql高级应用程序_mysql-sql高级应用

sql语言进阶典型操作order by- select * from play_list order bycreatetime;- select * from play_list order by bookedcount desc,createtime asc;order by语句用于根据指定的列对结果集进行排序order by语句默认按照升序对记录排序&#xff0c;使用desc则降序排序order by也…

HTML+CSS+JS实现 ❤️个人相册封面卡片❤️

效果演示&#xff1a; 代码目录&#xff1a; 主要代码实现&#xff1a; CSS样式&#xff1a; charset "utf-8"; import url("https://s2.pstatp.com/cdn/expire-1-M/font-awesome/4.7.0/css/font-awesome.min.css"); body {background-color: #1F1F1F;o…

python隐藏启动台_如何在Python中启动后台进程?

如何在Python中启动后台进程&#xff1f;我正在尝试将shell脚本移植到更易读的python版本。 原始shell脚本在后台使用“&#xff06;amp;”启动多个进程(实用程序&#xff0c;监视器等)。 如何在python中实现相同的效果&#xff1f; 我希望这些进程不会在python脚本完成时死掉。…

HTML+CSS+JS实现 ❤️swiper倾斜图片特效❤️

效果演示&#xff1a; 代码目录&#xff1a; 主要代码实现&#xff1a; CSS样式&#xff1a; .img_swiper {width: 800px;margin: 0 auto;position: relative; }.img {width: 100%;height: 100%; }.img_swiper .swiper-button-prev {width: 40px;height: 40px;background-im…

如何将c语言程序封装供python调用_C++调用python

C调用python在C/C中嵌入Python&#xff0c;可以使用Python提供的强大功能&#xff0c;通过嵌入Python可以替代动态链接库形式的接口&#xff0c;这样可以方便地根据需要修改脚本代码&#xff0c;而不用重新编译链接二进制的动态链接库。至少你可以把它当成文本形式的动态链接库…

HTML+CSS+JS实现 ❤️touchSlider图片滚动图片轮播❤️

效果演示&#xff1a; 代码目录&#xff1a; 主要代码实现&#xff1a; CSS样式&#xff1a; charset "utf-8"; * {margin: 0;padding: 0;list-style: none;border: 0; }body {width: 100%;margin: 0 auto;overflow: hidden }/* main_image */.main_visual {heigh…

win10配置mysql8.0_Win10下mysql 8.0.20 安装配置方法图文教程

Win10系统下MySQL 8.0.20安装和配置超详细教程MySQL下载MySQL直接去官网下载就行&#xff0c;选择community版本(免费)下载&#xff0c;链接。在select operating system中选择Microsoft Windows&#xff0c;下方对应出现最新版本的MySQL&#xff0c;目前是MySQL 8.0.20&#x…

HTML+CSS+JS实现 ❤️echarts省市区地图城市选择❤️

效果演示&#xff1a; 代码目录&#xff1a; 主要代码实现&#xff1a; CSS样式&#xff1a; * {margin: 0;padding: 0; }body {font-family: Exo, -apple-system, Open Sans, HelveticaNeue-Light, Helvetica Neue Light, Helvetica Neue, Hiragino Sans GB, Microsoft YaH…

基于SpringBoot+mybatis+layui就业管理系统设计和实现

&#x1f345; 作者主页&#xff1a;Java李杨勇 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java李杨勇公号作者✌ 简历模板、学习资料、面试题库、技术互助【关注我&#xff0c;都给你】 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f…

java集合清空_java 集合删除数据

public static void main(String[] args) {List list new ArrayList<>(Arrays.asList(1, 2, 3, 4));// 常规删除// list.removeIf(next -> next 3);Iterator iterator list.iterator();while (iterator.hasNext()) {// Integer next iterator.next();// 当不执行 …

HTML+CSS+JS实现 ❤️图片轮播幻灯片❤️

效果演示&#xff1a; 文末获取源码 代码目录&#xff1a; 主要代码实现&#xff1a; CSS样式&#xff1a; font-face {font-weight: normal;font-style: normal; }.csslider1 {display: inline-block;position: relative;max-width: 833px;width: 100%;margin-top: 10px; }.…

single java_java single Pattern 单例模式

单例模式是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式&#xff0c;它涉及到一个单一的类&#xff0c;该类自己负责创建自己的对象并且确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式&#xff0c;可以直接访问&#xff0c;不需要实例化…