• ShutdownHook学习


     在很多实际应用环境中,当用户关闭了应用程序的时候,需要做一些善后的清理工作。但是问题是用户有时候并不会按照推荐的方法关闭应用程序,更有可能不做清理工作。例如,在windows系统中,你打开了某个软件,那么软件开发商推荐退出软件的方式是在软件图标上右键退出或者在软件窗口上左键关闭,但是会有很多用户在实际操作中可能是打开任务管理器直接关闭进程,这样来达到关闭软件的目的。在这种情况中有可能会发生一些意外情况。

    幸运的是Java为程序员提供了一种优雅的方法可以在关闭过程中执行一些代码,这样就能确保那些负责善后处理的代码能够执行。
    在Java中,虚拟机会对两类事件进行响应,然后执行关闭操作:

    • 当调用`System.exit()`方法或者程序的最后一个非守护线程退出的时候,应用程序正常退出。
    • 当用户突然强制停止虚拟机的时候,例如`Ctrl+C`。

    幸运的是虚拟机在执行关闭操作的时候会经历以下两个阶段

    1. 如果有的话,虚拟机启动所有已经注册的关闭钩子。关闭钩子是之前通过Runtime类注册的线程,所有的关闭钩子会并发执行,一直到完成任务。
    2. 虚拟机根据情况调用所有没有被调用过的终结器(finalizer)。

    我们今天重点讨论第一个阶段。


    我们查看下在JDK文档中`Runtime`类的说明。

    public class Runtimeextends Object每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。可以通过 getRuntime 方法获取当前运行时。 
        
    应用程序不能创建自己的 Runtime 类实例。 
      
    void addShutdownHook(Thread hook) 注册新的虚拟机来关闭钩子。

    测试Demo

      /**
         * 测试 shutdownhook
         */
        public class ShutdownHookTest {
        
            public static void main(String[] args) {
                try {
                    Runtime.getRuntime().addShutdownHook(new MyHook());
                    System.out.println(Thread.currentThread().getName() + "准备睡眠 1秒");
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName() + "线程睡眠完毕,线程退出");
                } catch (Exception e) {
                    e.printStackTrace();
                }
        
            }
            static class MyHook extends Thread {
                @Override
                public void run() {
                    System.out.println("my shutdown hook run");
                }
            }
        }

     运行结果:

      

    main准备睡眠 1秒
    main线程睡眠完毕,线程退出
    my shutdown hook run
  • 相关阅读:
    编程基础之Java中继承和多态的理解
    2020年程序员是否过剩?
    如何自学编程,零基础适合学习Java或者Web前端吗,非科班的能学java吗?
    转行IT做后端开发,学python还是java?
    java和大数据哪个更有前途啊?零基础适合学哪个课程?
    随笔(二十)
    随笔(十九)
    随笔(十八)
    OSPF练习
    OSPF综合实验(二)
  • 原文地址:https://www.cnblogs.com/coldridgeValley/p/5449518.html
Copyright © 2020-2023  润新知