使用JVM钩子函数关闭资源
一、问题引入
背景
在编写一个需要持续在后台运行的程序的时候遇到了这样的场景:我的程序在主函数中创建了一个线程池周期性地执行任务,我希望主线程和线程池都持续运行,但如果收到外部的关闭信号时,主线程和线程池也都能同时退出。想到的就是程序结束的时候需要有一个stop()方法去关闭线程池,但是怎么控制这个stop()方法在我想要的时候调用,以什么形式去接收外部的关闭信号也成了需要考虑的问题。
原始思路
最开始的尝试是我将程序的运行和停止分别用"start"和"stop"两种状态表示,然后用一个状态文件state去记录当前的状态(程序启动时默认是"start"),如果想要关闭这个正在运行的程序,就去修改状态文件state,将里面内容变为"stop"。同时在主函数中打开这个状态文件,循环监听里面的内容,如果发现变为"stop",就去调用stop()方法执行关闭逻辑。按照这个思路,我写了一个简单的程序在IDEA中测试了一下效果,发现是可行的。但是当我将程序打包,在mac系统上运行jar包进行测试的时候,不知什么原因,程序总是读到state文件刚打开时的内容,不能检测到state文件的变化,无法按我设想的方式进行关闭。因此只能另想办法。
无意间看见JVM钩子函数的介绍,发现这可能正是我想要的,于是赶紧拿来试一试。
二、JVM钩子使用场景
JVM关闭的情况如下图所示分为三类,第一种是正常的关闭,第二种是异常关闭的情况,第三种是强制关闭的情况。
JVM钩子函数对于前两种方式都可以进行优雅的关闭,但是对最后一种强制关闭就不起作用了。
下面我会根据这三种JVM关闭过程进行简单演示。
正常关闭
代码如下:
public class TestJVMHook {public static void main(String[] args) {Runtime.getRuntime().addShutdownHook(new Thread(()->stop()));start();System.out.println("===程序正常结束===");}public static void start() {System.out.println("===调用start()方法===");}public static void stop() {System.out.println("===调用stop()方法===");}
}
运行结果:
===调用start()方法===
===程序正常结束===
===调用stop()方法===
可以看到,在钩子函数中声明了stop()方法,然后程序正常结束后会自动调用钩子函数。
异常关闭
异常关闭分为OOM和RuntimeException两种情况,我用除数为0的运行时异常来演示。
代码如下:
public class TestJVMHook {public static void main(String[] args) {Runtime.getRuntime().addShutdownHook(new Thread(()->stop()));start();int res = 10/0;System.out.println("===程序结束===");}public static void start() {System.out.println("===调用start()方法===");}public static void stop() {System.out.println("===调用stop()方法===");}
}
运行结果:
===调用start()方法===
===调用stop()方法===
Exception in thread "main" java.lang.ArithmeticException: / by zeroat com.example.TestJVMHook.main(TestJVMHook.java:9)
可以看到执行"10/0"时发生运行时异常,并不会正常打印下一行语句"=程序结束=",但仍然会自动调用钩子函数中stop()方法。
强制关闭
这里我们启动一个循环程序,然后手动去关闭它。
代码如下:
public class TestJVMHook {public static void main(String[] args) throws InterruptedException {Runtime.getRuntime().addShutdownHook(new Thread(()->stop()));int count = 1;start();while(true){System.out.println("循环计数器"+(count++));Thread.sleep(5*1000);}}public static void start() {System.out.println("===调用start()方法===");}public static void stop() {System.out.println("===调用stop()方法===");}
}
启动后查看进程id,然后通过"kill -9 <pid>"
强制关闭:
运行结果:
还是上面那段代码,再次启动,采用"kill <pid>"
关闭:
发现通过"kill"正常关闭可以有效调用钩子函数,但是"kill -9"强制关闭则不会调用钩子函数。
三、回归问题
经过一系列测试,验证了JVM钩子函数确实可以实现我想要的资源关闭效果。由于我的程序是一个循环程序,需要手动关闭,因此可以在关闭程序的脚本中通过 kill 的方式进行钩子函数的调用。
使用JVM钩子函数关闭资源相关推荐
- java钩子函数(hook)以spring源码为例
一.什么是钩子函数 请问在Spring中,如果JVM异常终止,Spring是如何保证会释放掉占用的资源,比如说数据库连接等资源呢?钩子函数非常简单,简单到只用摘抄一段Spring代码即可. 二.问题 ...
- JAVA-JVM的钩子函数
当jvm进程退出的时候,或者受到了系统的中断信号,hook线程就会启动,一个线程可以注入多个钩子,这是一个实例: import java.io.IOException; import java.uti ...
- 一起学并发编程 - 钩子函数(shutdownHook)
shutdownHook是一种特殊的结构,它允许开发人员插入JVM关闭时执行的一段代码.这种情况在我们需要做特殊清理操作的情况下很有用 <!-- more --> 用途 在Jboss,Je ...
- 解读鸿蒙轻内核的监控器:异常钩子函数
摘要:本篇先介绍下支持的异常钩子函数的类型,异常钩子函数的注册.执行等内部操作API接口,并介绍下使用异常钩子函数的操作接口. 本文分享自华为云社区<鸿蒙轻内核M核源码分析系列十七(1) 异常钩 ...
- Vue的过滤器,生命周期的钩子函数和使用Vue-router
一.过滤器 1.局部过滤器 在当前组件内部使用过滤器 给某些数据 添油加醋 //声明 filters:{'过滤器的名字':function(val,a,b){//a 就是alax ,val就是当前的数 ...
- k8s pod生命周期、初始化容器、钩子函数、容器探测、重启策略
pod结构 Pause容器 Pause容器是每个Pod都会有的一个根容器,它的作用有两个 可以以它为根据,评估整个pod的健康状态 可以在根容器上设置IP地址,其他容器都以此IP(Pod IP),以实 ...
- 哈哈,咱们团队早就不用try-catch-finally关闭资源了!
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 代码一定得写的优雅一点! 你还在使用try-catch-final ...
- 你还在使用 try-catch-finally 关闭资源?
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:何甜甜在吗 链接:https://juejin.im/pos ...
- 使用钩子函数[4] - 钩子链和 CallNextHookEx 的返回值
SetWindowsHookEx 函数的第一个参数表示钩子类型, 共有 14 种选择, 前面我们已经用过两种: WH_KEYBOARD.WH_MOUSE. 系统会为每一种类型的钩子建立一个表(那就是 ...
最新文章
- 【OpenCV】图像的通道分离
- 如何读取resources目录下的文件路径(九种方式)
- 【深度学习】在PyTorch中使用 LSTM 自动编码器进行时间序列异常检测
- ie6 select出现在浮动层上面的解决方法
- 周正宁:未来五年属于WebRTC+AV1
- java 解决汉诺塔问题
- sql 触发器_一键生成某个sql的html--记录执行计划、统计信息、触发器等
- 企业发卡修复版源码(短链二维码)
- 奈奎斯特定理和香农定理之科普篇
- 动软分享社区系统 v1.6 震撼发布!
- 用户自定义控件(UserControl)用法大全
- 大学计算机基础通俗易懂教材,大学计算机基础(21世纪高等学校计算机规划教材)...
- 内窥镜去反光的论文整理(转)
- Linux中断子系统(一)中断控制器GIC架构
- 中国大学MOOC课程《程序设计入门——C语言》 第8周编程练习
- Spatial AI
- H5 vue单页面 活体检测
- 自媒体推广应该怎么入手,如何去做
- linux系统读写eth网卡PHY寄存器工具mdio_cmd
- 楼宇自动化专用BACnet网关BL103
热门文章
- 追求代码质量: 不要被覆盖报告所迷惑
- python opencv 直方图均衡化_Python opencv—直方图/直方图均衡化/直方图比较,pythonopencv...
- html出现滚动条页面闪动,CSS3 calc实现滚动条出现页面不跳动闪动
- rbf神经网络原理_【新书推荐】【2012.12】智能优化算法原理与应用(李士勇)...
- kafka python client:PyKafka vs kafka-python
- Oracle 判断CLOB字段是否为null
- tuxedo linux 安装
- Linux 环境 简单启动 Java程序
- aspose-cell 使用
- 命令行运行postman