• ShutdownHook


    在看源码时,发现了 Runtime.getRuntime().addShutdownHook 的用法,看起来是在jvm退出前做了一些清理工作

    Runtime.getRuntime().addShutdownHook(new Thread() {
                @Override
                public void run() {
                    LOGGER.info("shut down cat client in runtime shut down hook!");
                    shutdown();
                }
            });

    抱着好奇的心态看了下addShutdownHook源码,结合方法描述总结如下:

    这是注册一个虚拟机的shutdown hook

    1. JVM 虚拟机会对以下两种情况下的shuts down 事件作出响应:

            程序正常退出 - exit

            也就是最后一个非守护线程退出或者调用了System.exit 方法退出

            虚拟机由于被中断而退出 - terminated

            ctrl + c 或者 系统事件如 用户登出(user logoff) 或者 系统shutdown (system shutdown)

    2. 不建议在shutdown hooks 中运行耗时长的任务(long-running),任务最好能快速的运行完

           当程序退出时,期望虚拟机也能及时的shutdown and exit

          当虚拟机由于用户登出或者系统shutdown 而退出(terminated)时,底层操作系统可能只允许一个固定的时间(a fixed amount of time)来shutdown and exit

    3. 在极少数情况下,虚拟机有可能会终止(abort),在这种情况下不会保证shutdown hooks是否会被执行

         这里的abort 指的是虚拟机由于外部的信号而退出,比如unix的signal或者windows中的 TerminateProcess

    4. 注册的hooks会并发的无序执行

     调用ApplicationShutdownHooks.add方法,注册hook,当程序退出时,jvm 调用runHooks方法,并发的执行所有hook线程,直到所有线程执行完毕后退出

    public void addShutdownHook(Thread hook) {
            SecurityManager sm = System.getSecurityManager();
            if (sm != null) {
                sm.checkPermission(new RuntimePermission("shutdownHooks"));
            }
            //调用add方法,将任务加入内存
            ApplicationShutdownHooks.add(hook);
        }

    ApplicationShutdownHooks

    static synchronized void add(Thread hook) {
            if(hooks == null)
                throw new IllegalStateException("Shutdown in progress");
    
            if (hook.isAlive())
                throw new IllegalArgumentException("Hook already running");
    
            if (hooks.containsKey(hook))
                throw new IllegalArgumentException("Hook previously registered");
                    //hooks是一个map  IdentityHashMap<Thread, Thread> hooks
            hooks.put(hook, hook);
        }
        
        //执行hooks
        static void runHooks() {
            Collection<Thread> threads;
            synchronized(ApplicationShutdownHooks.class) {
                threads = hooks.keySet();
                hooks = null;
            }
            // 并发的执行hook
            for (Thread hook : threads) {
                hook.start();
            }
            //直到所有的线程执行完退出
            for (Thread hook : threads) {
                try {
                    hook.join();
                } catch (InterruptedException x) { }
            }
        }
  • 相关阅读:
    day14_oracle数据库备份
    day13_存储过程小记
    day13_先沃联盟定时任务
    day13_自动抽取数据——监控存储过程
    [笔记]《HTTP权威指南》- 实体和编码
    [笔记]《白帽子讲Web安全》- Web框架安全
    [笔记]《Vue移动开发实战技巧》- Vue-router使用
    WPF与Win32互操作
    [翻译]HTML5
    学习资料收藏
  • 原文地址:https://www.cnblogs.com/tracer-dhy/p/10041643.html
Copyright © 2020-2023  润新知