zoukankan      html  css  js  c++  java
  • 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) { }
            }
        }
  • 相关阅读:
    shiro
    leetcode696 C++ 36ms 计算二进制子串
    leetcode557 C++ 56ms 反转字符串中的每个单词
    leetcode657 C++ 16ms 判断回环
    leetcode709 C++ 4ms 转换成小写字母
    leetcode141 C++ 8ms 环形链表
    leetcode160 C++ 32ms 相交链表
    leetcode234 C++ 28ms 回文链表
    leetcode203 C++ 28ms 删除链表中满足条件的节点
    leetcode83 C++ 12ms 删除有序链表中的重复元素
  • 原文地址:https://www.cnblogs.com/tracer-dhy/p/10041643.html
Copyright © 2011-2022 走看看