/** * Register a new shutdown hook. This is invoked when the program exits normally (because all * non-daemon threads ended, or because <code>System.exit</code> was invoked), or when the user * terminates the virtual machine (such as by typing ^C, or logging off). There is a security * check to add hooks, <code>RuntimePermission("shutdownHooks")</code>. * * <p>The hook must be an initialized, but unstarted Thread. The threads are run concurrently, and * started in an arbitrary order; and user threads or daemons may still be running. Once shutdown * hooks have started, they must all complete, or else you must use <code>halt</code>, to actually * finish the shutdown sequence. Attempts to modify hooks after shutdown has started result in * IllegalStateExceptions. * * <p>It is imperative that you code shutdown hooks defensively, as you do not want to deadlock, * and have no idea what other hooks will be running concurrently. It is also a good idea to * finish quickly, as the virtual machine really wants to shut down! * * <p>There are no guarantees that such hooks will run, as there are ways to forcibly kill a * process. But in such a drastic case, shutdown hooks would do little for you in the first place. * * @param hook an initialized, unstarted Thread * @throws IllegalArgumentException if the hook is already registered or run * @throws IllegalStateException if the virtual machine is already in the shutdown sequence * @throws SecurityException if permission is denied * @since 1.3 * @see #removeShutdownHook(Thread) * @see #exit(int) * @see #halt(int) */ public void addShutdownHook(Thread hook) { SecurityManager sm = SecurityManager.current; // Be thread-safe! if (sm != null) sm.checkPermission(new RuntimePermission("shutdownHooks")); if (hook.isAlive() || hook.getThreadGroup() == null) throw new IllegalArgumentException( "The hook thread " + hook + " must not have been already run or started"); synchronized (libpath) { if (exitSequence != null) throw new IllegalStateException( "The Virtual Machine is exiting. It is not possible anymore to add any hooks"); if (shutdownHooks == null) shutdownHooks = new HashSet(); // Lazy initialization. if (!shutdownHooks.add(hook)) throw new IllegalArgumentException(hook.toString() + " had already been inserted"); } }