您的位置:首页 > 其它

JVM Shutdown Hooks

2013-04-09 00:00 239 查看
Shutdown Hooks are a special construct that allows developers to plug in a piece of code to be executed when the JVM is shutting down. This comes in handy in cases where we need to do special clean up operations in case the VM is shutting down.

Handling this using the general constructs such as making sure that we call a special procedure before the application exists (calling System.exit(0) ) will not work for situations where the VM is shutting down due to an external reason (ex. kill request from O/S), or due to a resource problem (out of memory). As we will see soon, shutdown hooks solve this problem easily, by allowing you to provide an arbitrary code block, which will be called by the JVM when it is shutting down.

From the surface, using a shutdown hook is downright straight forward. All you have to do is simply write a class which extends the java.lang.Thread class, and provide the logic that you want to perform when the VM is shutting down, inside the public void run() method. Then you register an instance of this class as a shutdown hook to the VM by calling Runtime.getRuntime().addShutdownHook(Thread) method. If you need to remove a previously registered shutdown hook, the Runtime class provides the removeShutdownHook(Thread) method as well.

public class TestHook {
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
System.out.println("Shutdown Hook is running !");
}
});
System.out.println("Application Terminating ...");
}
}
While it is pretty simple to write a shutdown hook, one needs to know the internals behind the shutdown hooks to make use of those properly. Therefore, in this article, we will be exploring some of the ‘gotchas’ behind the shutdown hook design.
1. Shutdown Hooks may not be executed in some cases!

在某些情况下Shutdown钩子可能不会执行

First thing to keep in mind is that it is not guaranteed that shutdown hooks will always run(不能保证Shutdown钩子总是运行). If the JVM crashes due to some internal error, then it might crash down without having a chance to execute a single instruction. Also, if the O/S gives a SIGKILL signal (kill -9 in Unix/Linux) or TerminateProcess (Windows), then the application is required to terminate immediately without doing even waiting for any cleanup activities. In addition to the above, it is also possible to terminate the JVM without allowing the shutdown hooks to run by calling Runime.halt() method.

(操作系统发送SIGKILL信号或者调用Runtime.halt(),shutdown钩子不会被执行

Shutdown hooks are called when the application terminates normally (when all threads finish, or when System.exit(0) is called). Also, when the JVM is shutting down due to external causes such as user requesting a termination (Ctrl+C), a SIGTERM being issued by O/S (normal kill command, without -9), or when the operating system is shutting down.

(当应用正常结束-线程任务完成或System.exit(0)被调用,用户请求终止(Ctrl+C),操作系统SIGTERM 信号或者操作系统关闭,Shutdown钩子会被执行


2. Once started, Shutdown Hooks can be forcibly stopped before completion.
一旦开始,在完成前Shutdown钩子可以被强制停止

Although the hook starts execution, it is possible to be terminated before it completes, in cases such as operating system shutdowns. In this type of cases, the O/S waits for a process to terminate for a specified amount of time once the SIGTERM is given. If the process does not terminate within this time limit, then the O/S terminates the process forcibly by issuing a SIGTERM (or the counterparts in Windows). So it is possible that this happens when the shutdown hook is half-way through its execution.

(比如操作系统关闭时,OS发出SIGTERM 信号,在指定时间限制内等待进程终止,否则OS强制结束进程,所有有可能shutdown钩子只执行一半)

Therefore, it is advised to make sure that the Shutdown Hooks are written cautiously, ensuring that they finish quickly, and does not cause situations such as deadlocks. Also, the JavaDoc [1] specifically mentions that one should not perform long calculations or wait for User I/O operations in a shutdown hook.

(谨慎编写shutdown钩子,确保它能很快的执行完毕)

3. You can have more than one Shutdown Hook, but their execution order is not guaranteed.

多个shutdown钩子,他们的执行顺序不能保证

As you might have correctly guessed by the method name of addShutdownHook method (instead of setShutdownHook), you can register more than one shutdown hook. But the execution order of these multiple hooks is not guaranteed by the JVM. The JVM can execute shutdown hooks in any arbitrary order. Moreover, the JVM might execute all these hooks concurrently.

4. You cannot register / unregister Shutdown Hooks with in Shutdown Hooks

不能在shutdown钩子中,注册/注销shutdown钩子

Once the shutdown sequence is initiated by the JVM, it is not allowed to add more or remove any existing shutdown hooks. If this is attempted, the JVM throws IllegalStateException.

5. Once shutdown sequence starts, it can be stopped by Runtime.halt() only.

一旦shutdown启动,只能通过Runtime.halt()进行终止

Once the shutdown sequence starts, only Runtime.halt() (which forcefully terminates the JVM) can stop the execution of the shutdown sequence (except for external influences such as SIGKILL). This means that calling System.exit() with in a Shutdown Hook will not work. Actually, if you call System.exit() with in a Shutdown Hook, the VM will get stuck, and you have to terminate the process forcefully.

(一旦shutdown启动,只能通过Runtime.halt()进行终止(除了SIGKILL之类的),在shutdown钩子中调用System.exit() 是不能工作的,虚拟机会卡住,除非强制终止进程)

6. Using shutdown hooks require security permissions.

使用shutdown钩子需要安全权限

If you are using Java Security Managers, then the code which performs adding / removing of shutdown hooks need to have the shutdownHooks permission at runtime. If you invoke this method without the permission in a secure environment, then it will result in SecurityException.

7. Exceptions thrown by the Shutdown Hooks are treated same as exceptions thrown by any other code segment.

shutdown钩子抛出的异常跟其他代码块抛出的异常被认为是一样的


So the standard exception propagation mechanism applies here, and for uncaught exceptions, the default uncaught exception handlers will be invoked. For a detailed discussion regarding the uncaught exception handlers

More details regarding design decisions of the Java Shutdown Hooks API are explained in the ‘Design of the Shutdown Hooks API’ article [2]. It provides the rationale for using implementations of Thread class instead of Runnable interface, and many other decisions taken by the designers of the API.

One question you might have at this point is that with so much of cases where the Shutdown Hooks may not work as expected, relying on shutdown hooks to get things done might not be a good idea. While this is logical from one side of the argument, the counter-argument would be that it is impossible to provide a 100% fool-proof solution to this problem. For example, it is possible that the machine itself crashes due to some reason, or the power goes off without leaving the machine a chance to execute any cleanup operations as expected. With these pragmatic implications, shutdown hooks are the next best thing that is available to ensure that in most of the cases, the cleanup tasks will get executed.

In conclusion, the Shutdown Hooks API provide a simple way to plug-in some arbitrary code into the shutdown sequence of the JVM. While the API may seem to be simple, one should carefully consider the consequences and implications of the actions taken by a Shutdown Hook before writing one.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  shutdown hooks 钩子