// Private since we can't add a vtable slot in 4.1.x. private void exitNoChecks(int status) { if (runShutdownHooks()) exitInternal(status); // Someone else already called runShutdownHooks(). // Make sure we are not/no longer in the shutdownHooks set. // And wait till the thread that is calling runShutdownHooks() finishes. synchronized (libpath) { if (shutdownHooks != null) { shutdownHooks.remove(Thread.currentThread()); // Interrupt the exit sequence thread, in case it was waiting // inside a join on our thread. exitSequence.interrupt(); // Shutdown hooks are still running, so we clear status to // make sure we don't halt. status = 0; } } // If exit() is called again after the shutdown hooks have run, but // while finalization for exit is going on and the status is non-zero // we halt immediately. if (status != 0) exitInternal(status); while (true) try { exitSequence.join(); } catch (InterruptedException e) { // Ignore, we've suspended indefinitely to let all shutdown // hooks complete, and to let any non-zero exits through, because // this is a duplicate call to exit(0). } }
/** * Forcibly terminate the virtual machine. This call never returns. It is much more severe than * <code>exit</code>, as it bypasses all shutdown hooks and initializers. Use caution in calling * this! Of course, there is a security check, <code>checkExit(status)</code>. * * @param status the status to exit with * @throws SecurityException if permission is denied * @since 1.3 * @see #exit(int) * @see #addShutdownHook(Thread) */ public void halt(int status) { SecurityManager sm = SecurityManager.current; // Be thread-safe! if (sm != null) sm.checkExit(status); exitInternal(status); }