伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

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

来源:本站原创 浏览:106次 时间:2022-03-11
前言

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

正文

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中关于钩子的定义:

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)

首先来测试第一种

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

运行结果:

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

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

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

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

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

运行结果:

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

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

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

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

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

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

运行结果:


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

关注他


  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net