Shutdown 源码阅读

Shutdown

/**
 *  虚拟机关闭步骤
 * @since    1.3
 */
class Shutdown {
    /* 关闭状态 */
    private static final int RUNNING = 0;
    private static final int HOOKS = 1;
    private static final int FINALIZERS = 2;
    private static int state = RUNNING;

    /* Should we run all finalizers upon exit? */
    private static boolean runFinalizersOnExit = false;
    /**
     *  The system shutdown hooks are registered with a predefined slot.
     *  The list of shutdown hooks is as follows:
     *  (0) Console restore hook
     *  (1) Application hooks
     *  (2) DeleteOnExit hook
     */
    // 最多可注册的钩子函数个数
    private static final int MAX_SYSTEM_HOOKS = 10;
    private static final Runnable[] hooks = new Runnable[MAX_SYSTEM_HOOKS];

    // 当前运行钩子的索引
    private static int currentRunningHook = 0;

    /* The preceding static fields are protected by this lock */
    private static class Lock { };
    private static Object lock = new Lock();

    /* Lock object for the native halt method */
    private static Object haltLock = new Lock();

    /* Invoked by Runtime.runFinalizersOnExit */
    static void setRunFinalizersOnExit(boolean run) {
        synchronized (lock) {
            runFinalizersOnExit = run;
        }
    }

    /**
     *  添加一个关闭钩子
     *
     * @params slot 目标索引
     * @params registerShutdownInProgress   是否允许在关闭过程中注册钩子
     * @params hook 待注册的钩子
     */
    static void add(int slot, boolean registerShutdownInProgress, Runnable hook) {
        synchronized (lock) {
            // 目标索引处已经注册了
            if (hooks[slot] != null) {
                throw new InternalError("Shutdown hook at slot " + slot + " already registered");
            }

            if (!registerShutdownInProgress) {
                if (state > RUNNING) {
                    throw new IllegalStateException("Shutdown in progress");
                }
            } else {
                if (state > HOOKS || state == HOOKS && slot <= currentRunningHook) {
                    throw new IllegalStateException("Shutdown in progress");
                }
            }
            // 写入钩子
            hooks[slot] = hook;
        }
    }

    /**
     *  运行所有注册的关闭钩子
     */
    private static void runHooks() {
        for (int i=0; i < MAX_SYSTEM_HOOKS; i++) {
            try {
                Runnable hook;
                synchronized (lock) {
                    // acquire the lock to make sure the hook registered during
                    // shutdown is visible here.
                    currentRunningHook = i;
                    hook = hooks[i];
                }
                if (hook != null) {
                    hook.run();
                }
            } catch(final Throwable t) {
                if (t instanceof ThreadDeath) {
                    final ThreadDeath td = (ThreadDeath)t;
                    throw td;
                }
            }
        }
    }

    /**
     *  强制关闭虚拟机
     */
    static void halt(int status) {
        synchronized (haltLock) {
            halt0(status);
        }
    }

    static native void halt0(int status);

    /* Wormhole for invoking java.lang.ref.Finalizer.runAllFinalizers */
    private static native void runAllFinalizers();


    /**
     *  实际的关机顺序定义
     */
    private static void sequence() {
        synchronized (lock) {
            /* Guard against the possibility of a daemon thread invoking exit
             * after DestroyJavaVM initiates the shutdown sequence
             */
            if (state != HOOKS) {
                return;
            }
        }
        // 运行所有的关闭钩子
        runHooks();
        boolean rfoe;
        synchronized (lock) {
            state = FINALIZERS;
            rfoe = runFinalizersOnExit;
        }
        // 运行 Finalizers
        if (rfoe) {
            runAllFinalizers();
        }
    }

    /**
     * Invoked by Runtime.exit, which does all the security checks.
     */
    static void exit(int status) {
        boolean runMoreFinalizers = false;
        synchronized (lock) {
            if (status != 0) {
                runFinalizersOnExit = false;
            }
            switch (state) {
                case RUNNING:       /* Initiate shutdown */
                    state = HOOKS;
                    break;
                case HOOKS:         /* Stall and halt */
                    break;
                case FINALIZERS:
                    if (status != 0) {
                        /* Halt immediately on nonzero status */
                        halt(status);
                    } else {
                        /* Compatibility with old behavior:
                         * Run more finalizers and then halt
                         */
                        runMoreFinalizers = runFinalizersOnExit;
                    }
                    break;
            }
        }
        if (runMoreFinalizers) {
            runAllFinalizers();
            halt(status);
        }
        synchronized (Shutdown.class) {
            /* Synchronize on the class object, causing any other thread
             * that attempts to initiate shutdown to stall indefinitely
             */
            sequence();
            halt(status);
        }
    }


    /* Invoked by the JNI DestroyJavaVM procedure when the last non-daemon
     * thread has finished.  Unlike the exit method, this method does not
     * actually halt the VM.
     */
    static void shutdown() {
        // 修改状态
        synchronized (lock) {
            switch (state) {
                case RUNNING:       /* Initiate shutdown */
                    state = HOOKS;
                    break;
                case HOOKS:         /* Stall and then return */
                case FINALIZERS:
                    break;
            }
        }
        // 关机
        synchronized (Shutdown.class) {
            sequence();
        }
    }
}
上一篇:使用git hooks实现代码自动部署更新


下一篇:用webpack 打包css时遇到:Tapable.plugin is deprecated. Use new API on `.hooks` instead