What happens if System.exit is called from a shutdown hook?

喜欢而已 提交于 2019-12-09 15:00:14

问题


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;
}

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.

So I thought -

  1. What does calling exit from a shutdown hook do?
  2. What is the right way to error handle from a shutdown hook?

回答1:


Firstly, the easy answer: your process deadlocks.

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.

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();

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.

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.



来源:https://stackoverflow.com/questions/19552358/what-happens-if-system-exit-is-called-from-a-shutdown-hook

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!