java addShutdownHook

本文详细介绍了Java虚拟机的addShutdownHook方法,该方法用于注册虚拟机停止时的回调线程。文章解释了虚拟机停止的两种情况:正常退出和强制终止,并讨论了关闭回调线程的执行流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

addShutdownHook 注册一个新的虚拟机的停止回调。

Java虚拟机遇到以下两种事件停止。

 第一,程序正常退出,当最后一个非后台线程退出时,咖啡厅当System.exit方法被调用时。

  第二, 当用户中断时,像 ^C,或者系统的事件,例如登出,或者系统关机。

      关闭回调是一个只初始化,但并没有启动的线程。当虚拟机开始它的关闭步骤时,它会启动所有注册的关闭回调,这些回调以不确定次序的并发的方式运行。 当所有的回调结果后,如果启用了关闭时终结,那么会运行所有未调用的终结器。 最终,虚拟机会停止。 注意,后台线程在关闭过程中会继续运行。

    一旦关闭过程已经启动,只能通过调用halt来结束,它会强迫终止虚拟机。

     一旦关闭过程已经启动,不能注册新的关闭回调,也不能取消注册之前已经注册的回调。尝试任何一个操作会导致抛出 IllegalStateException.

    关闭回调运行在虚拟机生命周期的一个微妙的时刻,应该编码时保守一些。 特别的,写成线程安全的方式,尽量避免出现死锁。 它现不应该盲目依赖自身已经注册关闭回调的服务,这些服务可能处于关闭的过程中。尝试使用其它的基于线程的服务,像AWT事件分发线程,可能导致死锁。

    关闭回调应该快速结束它的工作。 当程序调用exit时,会期望虚拟机尽快结束。 当用户登出系统时,或者系统关闭时,底层的操作系统可能只允许一个固定的时间来关闭退出。 因此,尝试任何用户交互,或者在关闭回调时进行长时间计算是不明智的。

    在关闭回调中,未捕获异常像其它的线程异常一样处理。通过调用线程的ThreadGroup.uncaughtException方法。这个方法的默认实现是把异常的栈信息打印到标准错误输出里,然后终止线程。它不会导致虚拟机退出。

     在很少的情况下,虚拟机可能直接退出,即没有干净的关闭就停止运行。 在虚拟机被外部关闭时会发生,如在Unix系统中发出一个SIGKILL信号,或者 在Windows上调用TerminateProcess。 如果原生方法出现错误虚拟机也会直接停止,如内部数据结构损坏,或者 尝试访问不存在的内存。 如果虚拟机直接停止,那么不保证关闭回调会被运行。



/**
     * Registers a new virtual-machine shutdown hook.
     *
     * <p> 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>{@link #exit exit}</tt> (equivalently,
     *   {@link 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>
     *
     * <p> 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>{@link #exit exit}</tt>
     * method.
     *
     * <p> Once the shutdown sequence has begun it can be stopped only by
     * invoking the <tt>{@link #halt halt}</tt> method, which forcibly
     * terminates the virtual machine.
     *
     * <p> 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>{@link IllegalStateException}</tt> to be thrown.
     *
     * <p> 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.
     *
     * <p> Shutdown hooks should also finish their work quickly.  When a
     * program invokes <tt>{@link #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.
     *
     * <p> 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>{@link System#err}</tt> and
     * terminates the thread; it does not cause the virtual machine to exit or
     * halt.
     *
     * <p> 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
     * will be run. <p>
     *
     * @param   hook
     *          An initialized but unstarted <tt>{@link Thread}</tt> object
     *
     * @throws  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
     *
     * @throws  IllegalStateException
     *          If the virtual machine is already in the process
     *          of shutting down
     *
     * @throws  SecurityException
     *          If a security manager is present and it denies
     *          <tt>{@link RuntimePermission}("shutdownHooks")</tt>
     *
     * @see #removeShutdownHook
     * @see #halt(int)
     * @see #exit(int)
     * @since 1.3
     */
    public void addShutdownHook(Thread hook) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new RuntimePermission("shutdownHooks"));
        }
        ApplicationShutdownHooks.add(hook);
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值