如何优雅地关闭JVM?看看钩子函数如何一步实现,程序员开发指南

1、JVM正常关闭

直接看代码吧,

`public class Test {
public void start(){
Runtime.getRuntime().addShutdownHook(new Thread(()-> 
System.out.println("钩子函数被执行,可以在这里关闭资源")
));
}
public static void main(String[] args) throws Exception{
new Test().start();
System.out.println("主应用程序在执行");
}
}
//控制台输出
//主应用程序在执行
//钩子函数被执行,可以在这里关闭资源


看控制台打印,可以发现,主应用程序执行完之后就会调用钩子函数,接下来就会正式的关闭JVM。

### 2、异常关闭

还是直接看代码演示,这里我们演示异常关闭的第二种OOM的情况,我们可以先设置堆的大小为20M,然后在代码中创建一个500M的对象,这样就会OOM。参数是`-Xmx20M`;

`public class Test {
public void start(){
Runtime.getRuntime().addShutdownHook(new Thread(()-> 
System.out.println("钩子函数被执行,可以在这里关闭资源")
));
}
public static void main(String[] args) throws Exception{
new Test().start();
System.out.println("主应用程序在执行");
Runtime.getRuntime().halt(1);
byte[] b = new byte[500*1024*1024];
}
}
//控制台输出
//主应用程序在执行
//钩子函数被执行,可以在这里关闭资源


从控制台可以看出,钩子函数在异常关闭的时候依然会被调用。

### 3、强制关闭

这里我们使用`Runtime.getRuntime().halt()`来演示强势关闭。这个方法和`System.exit`的区别是,`System.exit`会执行钩子函数,但是`Runtime.getRuntime().halt()`不会。

`public class Test {
public void start(){
Runtime.getRuntime().addShutdownHook(new Thread(()-> 
System.out.println("钩子函数被执行,可以在这里关闭资源"

> **《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》**
>
> **【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享**

)
));
}
public static void main(String[] args) throws Exception{
new Test().start();
System.out.println("主应用程序在执行");
Runtime.getRuntime().halt(1);
}
}
//控制台输出
//主应用程序在执行


从上面代码的输出可以看出,调用了`Runtime.getRuntime().halt(1)`就会强制关闭JVM,钩子函数来不及执行就关闭了。而使用`System.exit`依然会执行。所以一般使用`System.exit`来关闭JVM。

### 4、移除钩子函数

上面演示了钩子函数的作用,有时候我们想移除也比较简单。

`public class Test {
public static void main(String[] args) throws Exception{
//new Test().start();
Thread willNotRun = new Thread(() -> 
System.out.println("Won't run!"));
Runtime.getRuntime().addShutdownHook(willNotRun);
System.out.println("主应用程序在执行");
Runtime.getRuntime().removeShutdownHook(willNotRun);
}
}
//控制台输出
//主应用程序在执行


OK,钩子函数的基本操作就写到这,使用起来比较简单,不过我之前看过Spring的启动流程,所以又去那个启动流程看了一波,发现也使用到了钩子函数。

## 二、典型应用场景

### 1、Spring使用

Spring在关闭上下文的时候,可以使用钩子函数来关闭残留的资源。方法是使用`ApplicationContext`注册一个钩子函数即可。

`ApplicationContext.registerShutdownHook();
//上面的这句代码可以分析进去看看
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值