java hooks_Java关闭钩子 - Shutdown Hook

1 //java.lang.Runtime

2 public voidaddShutdownHook(Thread hook) {3 SecurityManager sm =System.getSecurityManager();4 if (sm != null) {5 sm.checkPermission(new RuntimePermission("shutdownHooks"));6 }7 ApplicationShutdownHooks.add(hook);8 }9

10 //java.lang.ApplicationShutdownHooks

11 /*Add a new shutdown hook. Checks the shutdown state and the hook itself,12 * but does not do any security checks.13 */

14 static synchronized voidadd(Thread hook) {15 if(hooks == null)16 throw new IllegalStateException("Shutdown in progress");17

18 if(hook.isAlive())19 throw new IllegalArgumentException("Hook already running");20

21 if(hooks.containsKey(hook))22 throw new IllegalArgumentException("Hook previously registered");23

24 hooks.put(hook, hook);25 }26

27 //hooks有什么用?

28 /*Iterates over all application hooks creating a new thread for each29 * to run in. Hooks are run concurrently and this method waits for30 * them to finish.31 */

32 static voidrunHooks() {33 Collectionthreads;34 synchronized(ApplicationShutdownHooks.class) {35 threads =hooks.keySet();36 hooks = null;37 }38

39 for(Thread hook : threads) {40 hook.start();41 }42 for(Thread hook : threads) {43 while (true) {44 try{45 hook.join();46 break;47 } catch(InterruptedException ignored) {48 }49 }50 }51 }52

53

54 /*

55 这些钩子会在ApplicationShutdownHooks的初始化的时候,在static块里面被添加到Shudown的hooks里面56 java.lang.ApplicationShutdownHooks57 */

58 static{59 try{60 Shutdown.add(1 /*shutdown hook invocation order*/,61 false /*not registered if shutdown in progress*/,62 newRunnable() {63 public voidrun() {64 runHooks();65 }66 }67 );68 hooks = new IdentityHashMap<>();69 } catch(IllegalStateException e) {70 //application shutdown hooks cannot be added if71 //shutdown is in progress.

72 hooks = null;73 }74 }75 //注意,Shutdown的hooks和ApplicationShutdownHooks.hooks不同76 //添加到Shutdown的hooks

77 /**

78 * Add a new system shutdown hook. Checks the shutdown state and79 * the hook itself, but does not do any security checks.80 *81 * The registerShutdownInProgress parameter should be false except82 * registering the DeleteOnExitHook since the first file may83 * be added to the delete on exit list by the application shutdown84 * hooks.85 *86 * @params slot the slot in the shutdown hook array, whose element87 * will be invoked in order during shutdown88 * @params registerShutdownInProgress true to allow the hook89 * to be registered even if the shutdown is in progress.90 * @params hook the hook to be registered91 *92 *@throwsIllegalStateException93 * if registerShutdownInProgress is false and shutdown is in progress; or94 * if registerShutdownInProgress is true and the shutdown process95 * already passes the given slot96 */

97 static void add(int slot, booleanregisterShutdownInProgress, Runnable hook) {98 if (slot < 0 || slot >=MAX_SYSTEM_HOOKS) {99 throw new IllegalArgumentException("Invalid slot: " +slot);100 }101 synchronized(lock) {102 if (hooks[slot] != null)103 throw new InternalError("Shutdown hook at slot " + slot + " already registered");104

105 if (!registerShutdownInProgress) {106 if (currentRunningHook >= 0)107 throw new IllegalStateException("Shutdown in progress");108 } else{109 if (VM.isShutdown() || slot <=currentRunningHook)110 throw new IllegalStateException("Shutdown in progress");111 }112

113 hooks[slot] =hook;114 }115 }116

117 //执行真正的shutdown钩子

118 /*Run all system shutdown hooks.119 *120 * The system shutdown hooks are run in the thread synchronized on121 * Shutdown.class. Other threads calling Runtime::exit, Runtime::halt122 * or JNI DestroyJavaVM will block indefinitely.123 *124 * ApplicationShutdownHooks is registered as one single hook that starts125 * all application shutdown hooks and waits until they finish.126 */

127 private static voidrunHooks() {128 synchronized(lock) {129 /*Guard against the possibility of a daemon thread invoking exit130 * after DestroyJavaVM initiates the shutdown sequence131 */

132 if (VM.isShutdown()) return;133 }134

135 for (int i=0; i < MAX_SYSTEM_HOOKS; i++) {136 try{137 Runnable hook;138 synchronized(lock) {139 //acquire the lock to make sure the hook registered during140 //shutdown is visible here.

141 currentRunningHook =i;142 hook =hooks[i];143 }144 if (hook != null) hook.run();145 } catch(Throwable t) {146 if (t instanceofThreadDeath) {147 ThreadDeath td =(ThreadDeath)t;148 throwtd;149 }150 }151 }152

153 //set shutdown state

154 VM.shutdown();155 }156

157

158

159 //这个Shutdown.runHooks何时执行?

160 /*Invoked by Runtime.exit, which does all the security checks.161 * Also invoked by handlers for system-provided termination events,162 * which should pass a nonzero status code.163 */

164 static void exit(intstatus) {165 synchronized(lock) {166 if (status != 0 &&VM.isShutdown()) {167 /*Halt immediately on nonzero status*/

168 halt(status);169 }170 }171 synchronized (Shutdown.class) {172 /*Synchronize on the class object, causing any other thread173 * that attempts to initiate shutdown to stall indefinitely174 */

175 beforeHalt();176 runHooks();177 halt(status);178 }179 }180

181

182 /*Invoked by the JNI DestroyJavaVM procedure when the last non-daemon183 * thread has finished. Unlike the exit method, this method does not184 * actually halt the VM.185 */

186 static voidshutdown() {187 synchronized (Shutdown.class) {188 runHooks();189 }190 }191

192 //再进一步,这个exit/shutdown方法什么时候执行193 //exit方法再往上层追溯找到了我门熟悉的System.exit方法,shutdown暂时没找到调用之处194

195 //由此可见在执行System.exit方法之前会执行hooks里面所有的钩子

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值