Path: blob/master/src/java.base/share/classes/java/lang/ApplicationShutdownHooks.java
41152 views
/*1* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package java.lang;2526import java.util.*;2728/*29* Class to track and run user level shutdown hooks registered through30* {@link Runtime#addShutdownHook Runtime.addShutdownHook}.31*32* @see java.lang.Runtime#addShutdownHook33* @see java.lang.Runtime#removeShutdownHook34*/3536class ApplicationShutdownHooks {37/* The set of registered hooks */38private static IdentityHashMap<Thread, Thread> hooks;39static {40try {41Shutdown.add(1 /* shutdown hook invocation order */,42false /* not registered if shutdown in progress */,43new Runnable() {44public void run() {45runHooks();46}47}48);49hooks = new IdentityHashMap<>();50} catch (IllegalStateException e) {51// application shutdown hooks cannot be added if52// shutdown is in progress.53hooks = null;54}55}565758private ApplicationShutdownHooks() {}5960/* Add a new shutdown hook. Checks the shutdown state and the hook itself,61* but does not do any security checks.62*/63static synchronized void add(Thread hook) {64if(hooks == null)65throw new IllegalStateException("Shutdown in progress");6667if (hook.isAlive())68throw new IllegalArgumentException("Hook already running");6970if (hooks.containsKey(hook))71throw new IllegalArgumentException("Hook previously registered");7273hooks.put(hook, hook);74}7576/* Remove a previously-registered hook. Like the add method, this method77* does not do any security checks.78*/79static synchronized boolean remove(Thread hook) {80if(hooks == null)81throw new IllegalStateException("Shutdown in progress");8283if (hook == null)84throw new NullPointerException();8586return hooks.remove(hook) != null;87}8889/* Iterates over all application hooks creating a new thread for each90* to run in. Hooks are run concurrently and this method waits for91* them to finish.92*/93static void runHooks() {94Collection<Thread> threads;95synchronized(ApplicationShutdownHooks.class) {96threads = hooks.keySet();97hooks = null;98}99100for (Thread hook : threads) {101hook.start();102}103for (Thread hook : threads) {104while (true) {105try {106hook.join();107break;108} catch (InterruptedException ignored) {109}110}111}112}113}114115116