/* Should we run all finalizers upon exit? */ privatestaticboolean 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
if (!registerShutdownInProgress) { if (state > RUNNING) thrownew IllegalStateException("Shutdown in progress"); } else { if (state > HOOKS || (state == HOOKS && slot <= currentRunningHook)) thrownew IllegalStateException("Shutdown in progress"); } // 刚才ApplicationShutdownHooks传的是:(1) Application hooks hooks[slot] = hook; } }
// 除了add,这是唯一引用hooks的地方了 // 可以看出是顺序执行3种钩子 privatestaticvoidrunHooks(){ 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(Throwable t) { if (t instanceof ThreadDeath) { ThreadDeath td = (ThreadDeath)t; throw td; } } } }
// 执行钩子的地方 privatestaticvoidsequence(){ 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; } if (rfoe) runAllFinalizers(); }
// 下面两个方法是我们触发应用关闭的途径,均可执行钩子
/* Invoked by Runtime.exit, which does all the security checks. * Also invoked by handlers for system-provided termination events, * which should pass a nonzero status code. */ // 强行翻译:通过Runtime.exit调用 // 这是我们可以在程序中调用到的 staticvoidexit(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. */ // 强行翻译:最后一个非守护线程结束后通过本地接口(JNI)调用。和exit方法不同,此方法没有真正停止虚拟机 // 这个方法没有找到调用的代码 staticvoidshutdown(){ synchronized (lock) { switch (state) { case RUNNING: /* Initiate shutdown */ state = HOOKS; break; case HOOKS: /* Stall and then return */ case FINALIZERS: break; } } synchronized (Shutdown.class) { sequence();// 执行钩子 } }