如果从关机钩子调用System.exit会发生什么? [英] What happens if System.exit is called from a shutdown hook?

查看:160
本文介绍了如果从关机钩子调用System.exit会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Java中关机相当复杂-有很多清理工作要做.特别是,我试图找出如何从关闭挂接线程中进行错误处理.我的代码当前包含以下内容:

I have a rather complicated shutdown in Java - there's a lot of clean up work to do. In particular I'm trying to figure out how to error handle from a shutdown hook thread. My code includes this currently:

try {
    return shutdownPromise = doShutdown();
}
catch (Throwable exc) {
    logger.error("An exception was thrown while shutting down the application.", exc);  
    System.exit(1);
    return null;
}

当我最初写这篇文章时,我本质上认为,关机时的错误应该直接出现在exit上.但是exit并不是那么低.它称为关闭钩子.

When I originally wrote this I essentially thought, an error in shutdown should just go straight to exit. But exit is not so low level; it calls the shutdown hooks.

所以我想-

  1. 从关闭挂接退出的调用有什么作用?
  2. 从挂机钩进行错误处理的正确方法是什么?

推荐答案

首先,简单的答案:您的进程陷入僵局.

Firstly, the easy answer: your process deadlocks.

System.exit结束调用Shutdown.exit,其结尾为

System.exit winds up calling Shutdown.exit, which ends with this code block:

synchronized (Shutdown.class) {
     /* Synchronize on the class object, causing any other thread
      * that attempts to initiate shutdown to stall indefinitely
      */
     sequence();
     halt(status);
}

此评论完全正确.但是要了解这一点,我们需要确切地了解一下关机钩子的作用.

The comment is completely accurate. But to understand this we need to see exactly what the the shutdown hook does.

关闭挂钩是通过ApplicationShutdownHooks.add添加的,如此处的答案所述.请注意,上述sequence方法最终会出现在

Shutdown hooks are added via ApplicationShutdownHooks.add, as explained in this answer here. Note that the sequence method above eventually winds up on this line of code in Shutdown.runHooks:

if (hook != null) hook.run();

首先,请注意这些挂钩不是您的应用程序关闭挂钩.它们是系统关闭挂钩,它们是不同的,其中之一负责确保您的应用程序关闭挂钩运行.请注意,这是 run ,而不是 start .换句话说,它阻止.这些关闭挂钩之一是系统挂钩,该挂钩同时启动所有应用程序关闭挂钩(您可以自己或在链接的答案中跟踪此代码),然后阻塞,直到使用Thread.join调用将其全部完成为止.其中之一就是您的应用程序关闭挂钩-如果它调用System.exit,它将一直等待永远锁定Shutdown.class.

Firstly, note these hooks are not your application shutdown hooks. They are system shutdown hooks, which are different, and one of them is responsible for ensuring your application shutdown hooks run. Notice that is run, not start. In other words, it blocks. One of these shutdown hooks will be a system hook that concurrently starts all the application shutdown hooks (you can trace this code for yourself or in linked answer), then blocks until they all complete using a Thread.join call. One of these will be your application shutdown hook - which, if it calls System.exit, will be waiting to get the lock on Shutdown.class forever.

下一步,愚蠢的答案:改为致电Runtime.getRuntime().halt().我之所以说愚蠢的答案",是因为这可能是您要执行的较低级别的操作,而不是退出.如果System.exit表示完全关闭失败,那么halt是硬关闭,将始终立即成功.

Next, the dumb answer: call Runtime.getRuntime().halt() instead. I say "the dumb answer" because this is probably the slightly lower level thing you were looking to do instead of exit. If System.exit represents a clean shutdown that failed, then halt is a hard shutdown that will always succeed immediately.

接下来,更明智的答案:可能什么都不是.出于以下原因,只需关闭您的关机钩子即可.您的关闭钩子不属于该关闭器-尤其是,可能还有其他关闭钩子需要执行其工作.相反,我怀疑此挂钩的职责之一是最终强制硬关闭.我建议立即将其创建为延迟任务,然后将该钩子正常完成.

Next, the smarter answer: probably nothing. Just let your shutdown hook finish, for the following reasons. Your shutdown hook does not own the shutdown - in particular, there may be other shutdown hooks that need to do their work. Conversely, I suspect one of the responsibilities of this hook is to force a hard shutdown eventually. I would recommend creating that as a delayed task right away then letter this hook complete normally.

这篇关于如果从关机钩子调用System.exit会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆