Java程序经常也会遇到进程挂掉的情况,一些状态没有正确的保存下来,这时候就需要在JVM关掉的时候执行一些清理现场的代码。JAVA中的ShutdownHook提供了比较好的方案。

JDK提供了Java.Runtime.addShutdownHook(Thread hook)方法,可以注册一个JVM关闭的钩子,这个钩子可以在一下几种场景中被调用:

  1. 程序正常退出
  2. 使用System.exit()
  3. 终端使用Ctrl+C触发的中断
  4. 系统关闭
  5. OutOfMemory宕机
  6. 使用Kill pid命令干掉进程(注:在使用kill -9 pid时,是不会被调用的)

下面是JDK1.7中关于钩子的定义:

1
2
3
4
5
6
7
8
9
10
11
    public void addShutdownHook(Thread hook)
参数:
    hook - An initialized but unstarted Thread object
抛出:
    IllegalArgumentException - If the specified hook has already been registered, or if it can be determined that the hook is already running or has already been run
    IllegalStateException - If the virtual machine is already in the process of shutting down
    SecurityException - If a security manager is present and it denies RuntimePermission("shutdownHooks")
从以下版本开始:
    1.3
另请参见:
    removeShutdownHook(java.lang.Thread), halt(int), exit(int)

首先来测试第一种,程序正常退出的情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.hook; 
import java.util.concurrent.TimeUnit; 
public class HookTest 
    public void start() 
    
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { 
            @Override 
            public void run() 
            
                System.out.println("Execute Hook....."); 
            
        })); 
    
    public static void main(String[] args) 
    
        new HookTest().start(); 
        System.out.println("The Application is doing something"); 
        try 
        
            TimeUnit.MILLISECONDS.sleep(5000); 
        
        catch (InterruptedException e) 
        
            e.printStackTrace(); 
        
    
}

运行结果:

1
2
The Application is doing something 
Execute Hook.....

如上可以看到,当main线程运行结束之后就会调用关闭钩子。

下面再来测试第五种情况(顺序有点乱,表在意这些细节):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.hook; 
import java.util.concurrent.TimeUnit; 
public class HookTest2 
    public void start() 
    
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { 
            @Override 
            public void run() 
            
                System.out.println("Execute Hook....."); 
            
        })); 
    
    public static void main(String[] args) 
    
        new HookTest().start(); 
        System.out.println("The Application is doing something"); 
        byte[] b = new byte[500*1024*1024]; 
        try 
        
            TimeUnit.MILLISECONDS.sleep(5000); 
        
        catch (InterruptedException e) 
        
            e.printStackTrace(); 
        
    
}

运行参数设置为:-Xmx20M  这样可以保证会有OutOfMemoryError的发生。

运行结果:

1
2
3
4
The Application is doing something 
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 
    at com.hook.HookTest2.main(HookTest2.java:22
Execute Hook.....

可以看到程序遇到内存溢出错误后调用关闭钩子,与第一种情况中,程序等待5000ms运行结束之后推出调用关闭钩子不同。

接下来再来测试第三种情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.hook; 
import java.util.concurrent.TimeUnit; 
public class HookTest3 
    public void start() 
    
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { 
            @Override 
            public void run() 
            
                System.out.println("Execute Hook....."); 
            
        })); 
    
    public static void main(String[] args) 
    
        new HookTest3().start(); 
        Thread thread = new Thread(new Runnable(){ 
            @Override 
            public void run() 
            
                while(true
                
                    System.out.println("thread is running...."); 
                    try 
                    
                        TimeUnit.MILLISECONDS.sleep(100); 
                    
                    catch (InterruptedException e) 
                    
                        e.printStackTrace(); 
                    
                
            
        }); 
        thread.start(); 
    
}

在命令行中编译:javac com/hook/HookTest3.java

在命令行中运行:Java com.hook.HookTest3  (之后按下Ctrl+C)

运行结果:


可以看到效果如预期。
还有几种情况就不一一列出了,有兴趣的读者可以试一下。

from: 朱小厮

http://www.importnew.com/22765.html

JAVA虚拟机关闭钩子(Shutdown Hook)相关推荐

  1. java hook全局钩子,牛逼骚操作:Java 虚拟机关闭钩子(Shutdown Hook)!

    码农每日一题 长按关注,工作日每天分享一个技术知识点. Shutdown Hooks 是一种特殊的结构,它允许开发人员插入 JVM 关闭时执行的一段代码. 用途 Application 正常退出(所有 ...

  2. layui.open 关闭之后触发_JAVA虚拟机关闭钩子(Shutdown Hook)

    前言 当你认真的去看一个组件的源码的时候,你会经常看见这种关闭钩子的函数,如果你不了解的话,谷歌一下,你就会发现如下文章就是搜索引擎出来的第一篇,不愧是出自我们优秀的厮哒哒之笔. 正文 Java 程序 ...

  3. java8:关闭钩子shutdown hook

    参考资料: <Java中的关闭钩子(shutdown hook)> <JVM 的关闭钩子> 写在开头:本文为学习后的总结,可能有不到位的地方,错误的地方,欢迎各位指正. 目录 ...

  4. nodemanager不能正常关闭_Java虚拟机关闭钩子(Shutdown hook)

    作者:俩右 出处:https://segmentfault.com/a/1190000038298447 源码点击 study:https://github.com/xiaoshuanglee/stu ...

  5. spark学习-61-源代码:ShutdownHookManager虚拟机关闭钩子管理器

    Java程序经常也会遇到进程挂掉的情况,一些状态没有正确的保存下来,这时候就需要在JVM关掉的时候执行一些清理现场的代码. JAVA中的ShutdownHook提供了比较好的方案. JDK提供了Jav ...

  6. 深入JVM关闭与关闭钩子

    1. 简述JVM关闭 通常而言,对于JVM的关闭我们很少去关注,但是了解JVM的关闭能帮我们在JVM关闭时做一些合理的事情.首先JVM的关闭方式可以分为三种: 正常关闭:当最后一个非守护线程结束或者调 ...

  7. 关闭钩子(shutdown hool)

    Java提供了一种优雅的方式供程序员来使用,这样可以保证清理代码的执行.本章将会说明如何使用一个关闭钩子(shutdown hool)来保证清理代码一定会被执行. 在Java中,虚拟机遇到两种事件的时 ...

  8. Java中的JVM关闭钩子

    java面试题网站:www.javaoffers.com Java中的JVM关闭钩子 (翻译篇)关机钩子 也叫 关闭钩子 关机钩子是一种特殊的构造,允许开发人员插入一段代码,以便在JVM关闭时执行.当 ...

  9. Java 进程的退出机制与Shutdown hook

    基本概念 进程与线程:一个进程包含多个线程,一个进程中所有线程都退出后,该进程才会退出. 用户线程与守护线程:任一用户线程未退出,JVM进程不退出,当所有用户线程都退出时, 守护线程线程自动退出. S ...

最新文章

  1. [毕业生的商业软件开发之路]尽早暴露错误原则
  2. 当前版本与卡刷包android_Z2 Android 6.0.1卡刷包 23.5.0.486发布,快刷起来!(来自XDA)...
  3. sqlite3 学习
  4. 201312-2_ISBN号码
  5. 人行征信报告(下)——探秘二代征信的内容
  6. 都说「跳一跳」是微信抄袭了育碧,万万没想到,他们在一起了!
  7. opencv人脸关键点生成掩膜并替换
  8. __line__ php,hitcon 2018受虐笔记一:one-line-php-challenge 学习
  9. caffe安装简易教程
  10. python实现计算器功能、输入加减乘除、不是就跳出_使用Python实现计算器功能
  11. 三维激光雷达路沿检测
  12. Centos 7下PCIe Bus Error: severity=Corrected, type=Data Link Layer解决方案
  13. 固态硬盘是什么接口_电脑M.2接口讲究多:读懂固态硬盘完整规格
  14. 【强烈推荐一款吊炸天的 Kafka 图形化工具 Eagle】
  15. 超级抠图:Super PhotoCut for Mac
  16. 同花顺_代码解析_技术指标_S
  17. java base64转字图片、图片转base64字符串
  18. Windows内存详解(四)OD内存断点初步分析
  19. 知识点------js判断早上好,上午好,下午好,傍晚好,晚上好
  20. 用java编程画机器猫_用JAVA编程:编写GUI程序,模拟龟兔赛跑游戏

热门文章

  1. 【Python】Python常用的Series 和 Dataframe处理方法
  2. 【风控建模】互联网金融-机器学习及评分卡构建
  3. 大象转身,地表最强投行高盛开启转型之路
  4. 信用风险模型(申请评分、行为评分)与数据准备(违约期限、WOE转化)
  5. 白话Elasticsearch43-深入聚合数据分析之案例实战__排序:按每种颜色的平均销售额升序排序
  6. 白话Elasticsearch33-深入聚合数据分析之案例实战bucket + metrics 统计每种颜色电视平均价格
  7. Spring-AOP @AspectJ切点函数之execution()
  8. 心中有“树”:数据结构之树详解
  9. 学习笔记Kafka(一)—— Kafka简介
  10. 学习笔记——matplotlib学习