FileDocCategorySizeDatePackage
Shutdown.javaAPI DocJava SE 5 API6556Fri Aug 26 14:57:04 BST 2005java.lang

Shutdown

public class Shutdown extends Object
Package-private utility class containing data structures and logic governing the virtual-machine shutdown sequence.
author
Mark Reinhold
version
1.11, 03/12/19
since
1.3

Fields Summary
private static final int
RUNNING
private static final int
HOOKS
private static final int
FINALIZERS
private static int
state
private static boolean
runFinalizersOnExit
private static HashSet
hooks
private static Object
lock
private static Object
haltLock
Constructors Summary
Methods Summary
static voidadd(java.lang.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);
	    }
	}
    
static voidexit(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);
	}
    
static voidhalt(int status)

        synchronized (haltLock) {
            halt0(status);
        }
    
static native voidhalt0(int status)

static booleanremove(java.lang.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;
	    }
	}
    
private static native voidrunAllFinalizers()

private static voidrunHooks()

	/* 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;
	    }
	}
    
private static voidsequence()

	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();
    
static voidsetRunFinalizersOnExit(boolean run)


    /* Invoked by Runtime.runFinalizersOnExit */
        
	synchronized (lock) {
	    runFinalizersOnExit = run;
	}
    
static voidshutdown()

	synchronized (lock) {
	    switch (state) {
	    case RUNNING:	/* Initiate shutdown */
		state = HOOKS;
		break;
	    case HOOKS:		/* Stall and then return */
	    case FINALIZERS:
		break;
	    }
	}
	synchronized (Shutdown.class) {
	    sequence();
	}