shutdown.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 262 行

JAVA
262
字号
/* * @(#)Shutdown.java	1.17 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * */package java.lang;import java.util.HashSet;import java.util.Iterator;import sun.misc.ThreadRegistry;/** * Package-private utility class containing data structures and logic * governing the virtual-machine shutdown sequence. * * @author   Mark Reinhold * @version  1.8, 00/05/03 * @since    1.3 */class Shutdown {    /* Wrapper class for registered hooks, to ensure that hook identity is     * object identity rather than .equals identity     */    private static class WrappedHook {	private Thread hook;	WrappedHook(Thread t) {	    hook = t;	}	public int hashCode() {	    return System.identityHashCode(hook);	}	public boolean equals(Object o) {	    if (!(o instanceof WrappedHook)) return false;	    return (((WrappedHook)o).hook == hook);	}    }    /* Shutdown state */    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 set of registered, wrapped hooks, or null if there aren't any */    private static HashSet hooks = null;    /* The preceding static fields are protected by this lock */    private static class Lock { };    private static Object lock = new Lock();    /* Invoked by Runtime.runFinalizersOnExit */    static void setRunFinalizersOnExit(boolean run) {	synchronized (lock) {	    runFinalizersOnExit = run;	}    }    /* Add a new shutdown hook.  Checks the shutdown state and the hook itself,     * but does not do any security checks.     */    static void add(Thread hook) {	synchronized (lock) {	    if (state > RUNNING)		throw new IllegalStateException("Shutdown in progress");	    if (hook.isAlive())		throw new IllegalArgumentException("Hook already running");	    if (hooks == null) {		hooks = new HashSet(11);		hooks.add(new WrappedHook(hook));		Terminator.setup();	    } else {		WrappedHook wh = new WrappedHook(hook);		if (hooks.contains(wh))		    throw new IllegalArgumentException("Hook previously registered");		hooks.add(wh);	    }	}    }    /* Remove a previously-registered hook.  Like the add method, this method     * does not do any security checks.     */    static boolean remove(Thread hook) {	synchronized (lock) {	    if (state > RUNNING)		throw new IllegalStateException("Shutdown in progress");	    if (hook == null) throw new NullPointerException();	    if (hooks == null) {		return false;	    } else {		boolean rv = hooks.remove(new WrappedHook(hook));		if (rv && hooks.isEmpty()) {		    hooks = null;		    Terminator.teardown();		}		return rv;	    }	}    }    /* Run all registered shutdown hooks     */    private static void runHooks() {	/* We needn't bother acquiring the lock just to read the hooks field,	 * since the hooks can't be modified once shutdown is in progress	 */	if (hooks == null) return;	for (Iterator i = hooks.iterator(); i.hasNext();) {	    ((WrappedHook)(i.next())).hook.start();	}	for (Iterator i = hooks.iterator(); i.hasNext();) {	    try {		((WrappedHook)(i.next())).hook.join();	    } catch (InterruptedException x) {		continue;	    }	}    }    /* The true native halt method; also invoked by Runtime.halt     * after doing the necessary security checks     */    static native void halt(int status);    /* Wormhole for invoking java.lang.ref.Finalizer.runAllFinalizers */    private static native void runAllFinalizers();    /* The actual shutdown sequence is defined here.     *     * If it weren't for runFinalizersOnExit, this would be simple -- we'd just     * run the hooks and then halt.  Instead we need to keep track of whether     * we're running hooks or finalizers.  In the latter case a finalizer could     * invoke exit(1) to cause immediate termination, while in the former case     * any further invocations of exit(n), for any n, simply stall.  Note that     * if on-exit finalizers are enabled they're run iff the shutdown is     * initiated by an exit(0); they're never run on exit(n) for n != 0 or in     * response to SIGINT, SIGTERM, etc.     */    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;	}	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.     */    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();	}    }    private static void waitAllUserThreadsExitAndShutdown() {	ThreadRegistry.waitAllUserThreadsExit();	shutdown();    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?