/// <summary> /// De-registers a previously-registered virtual-machine shutdown hook. <para> /// /// </para> /// </summary> /// <param name="hook"> the hook to remove </param> /// <returns> <tt>true</tt> if the specified hook had previously been /// registered and was successfully de-registered, <tt>false</tt> /// otherwise. /// </returns> /// <exception cref="IllegalStateException"> /// If the virtual machine is already in the process of shutting /// down /// </exception> /// <exception cref="SecurityException"> /// If a security manager is present and it denies /// <tt><seealso cref="RuntimePermission"/>("shutdownHooks")</tt> /// </exception> /// <seealso cref= #addShutdownHook </seealso> /// <seealso cref= #exit(int) /// @since 1.3 </seealso> public virtual bool RemoveShutdownHook(Thread hook) { SecurityManager sm = System.SecurityManager; if (sm != null) { sm.CheckPermission(new RuntimePermission("shutdownHooks")); } return(ApplicationShutdownHooks.Remove(hook)); }
/// <summary> /// Registers a new virtual-machine shutdown hook. /// /// <para> The Java virtual machine <i>shuts down</i> in response to two kinds /// of events: /// /// <ul> /// /// <li> The program <i>exits</i> normally, when the last non-daemon /// thread exits or when the <tt><seealso cref="#exit exit"/></tt> (equivalently, /// <seealso cref="System#exit(int) System.exit"/>) method is invoked, or /// /// <li> The virtual machine is <i>terminated</i> in response to a /// user interrupt, such as typing <tt>^C</tt>, or a system-wide event, /// such as user logoff or system shutdown. /// /// </ul> /// /// </para> /// <para> A <i>shutdown hook</i> is simply an initialized but unstarted /// thread. When the virtual machine begins its shutdown sequence it will /// start all registered shutdown hooks in some unspecified order and let /// them run concurrently. When all the hooks have finished it will then /// run all uninvoked finalizers if finalization-on-exit has been enabled. /// Finally, the virtual machine will halt. Note that daemon threads will /// continue to run during the shutdown sequence, as will non-daemon threads /// if shutdown was initiated by invoking the <tt><seealso cref="#exit exit"/></tt> /// method. /// /// </para> /// <para> Once the shutdown sequence has begun it can be stopped only by /// invoking the <tt><seealso cref="#halt halt"/></tt> method, which forcibly /// terminates the virtual machine. /// /// </para> /// <para> Once the shutdown sequence has begun it is impossible to register a /// new shutdown hook or de-register a previously-registered hook. /// Attempting either of these operations will cause an /// <tt><seealso cref="IllegalStateException"/></tt> to be thrown. /// /// </para> /// <para> Shutdown hooks run at a delicate time in the life cycle of a virtual /// machine and should therefore be coded defensively. They should, in /// particular, be written to be thread-safe and to avoid deadlocks insofar /// as possible. They should also not rely blindly upon services that may /// have registered their own shutdown hooks and therefore may themselves in /// the process of shutting down. Attempts to use other thread-based /// services such as the AWT event-dispatch thread, for example, may lead to /// deadlocks. /// /// </para> /// <para> Shutdown hooks should also finish their work quickly. When a /// program invokes <tt><seealso cref="#exit exit"/></tt> the expectation is /// that the virtual machine will promptly shut down and exit. When the /// virtual machine is terminated due to user logoff or system shutdown the /// underlying operating system may only allow a fixed amount of time in /// which to shut down and exit. It is therefore inadvisable to attempt any /// user interaction or to perform a long-running computation in a shutdown /// hook. /// /// </para> /// <para> Uncaught exceptions are handled in shutdown hooks just as in any /// other thread, by invoking the <tt>{@link ThreadGroup#uncaughtException /// uncaughtException}</tt> method of the thread's <tt>{@link /// ThreadGroup}</tt> object. The default implementation of this method /// prints the exception's stack trace to <tt><seealso cref="System#err"/></tt> and /// terminates the thread; it does not cause the virtual machine to exit or /// halt. /// /// </para> /// <para> In rare circumstances the virtual machine may <i>abort</i>, that is, /// stop running without shutting down cleanly. This occurs when the /// virtual machine is terminated externally, for example with the /// <tt>SIGKILL</tt> signal on Unix or the <tt>TerminateProcess</tt> call on /// Microsoft Windows. The virtual machine may also abort if a native /// method goes awry by, for example, corrupting internal data structures or /// attempting to access nonexistent memory. If the virtual machine aborts /// then no guarantee can be made about whether or not any shutdown hooks /// </para> /// will be run. <para> /// /// </para> /// </summary> /// <param name="hook"> /// An initialized but unstarted <tt><seealso cref="Thread"/></tt> object /// </param> /// <exception cref="IllegalArgumentException"> /// If the specified hook has already been registered, /// or if it can be determined that the hook is already running or /// has already been run /// </exception> /// <exception cref="IllegalStateException"> /// If the virtual machine is already in the process /// of shutting down /// </exception> /// <exception cref="SecurityException"> /// If a security manager is present and it denies /// <tt><seealso cref="RuntimePermission"/>("shutdownHooks")</tt> /// </exception> /// <seealso cref= #removeShutdownHook </seealso> /// <seealso cref= #halt(int) </seealso> /// <seealso cref= #exit(int) /// @since 1.3 </seealso> public virtual void AddShutdownHook(Thread hook) { SecurityManager sm = System.SecurityManager; if (sm != null) { sm.CheckPermission(new RuntimePermission("shutdownHooks")); } ApplicationShutdownHooks.Add(hook); }