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();
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章