Java shutdown hooks
Java allows you to add shutdown hooks to your code. A shutdown hook is simply a thread that has been left in the initialized state. When your JVM is about to shutdown, the shutdown hook thread kicks in. The finalization processes of java objects run after the shutdown hooks complete. The JVM allows you to register more than one shutdown hook.
Let us take a look at how this is done
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | public class Task { public static void main(String[] args) { Runtime runtime = Runtime.getRuntime(); Thread thread = new Thread(new ShutDownListener()); runtime.addShutdownHook(thread); someProcess(); } private static void someProcess() { try { System.out.println("I am busy"); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } class ShutDownListener implements Runnable { @Override public void run() { System.out.println("I am shutting down"); } } |
The Task class is a simple class that runs a process. Once this process finishes up, we want the JVM to run a shutdown hook to notify us that the JVM is shutting down. When this program is run, the output is
1 2 | I am busy I am shutting down |
Nice !
Lets experiment a little more. How robust is a shutdown hook ? After the someProcess() method is called let us analyze what will happen when one of the following statements are added
1 2 3 | System.exit(-1); throw new NullPointerException(); throw new OutOfMemoryError(); |
The shutdown hook still executes. So the hook will execute even if there are errors / exceptions in the main program. What happens when the hook itself throws an error / exception ?. The uncaught exception will by default be printed to System.err and propagated to the VM. The behavior is comparable to a thread encountering an uncaught exception.
It seems pretty robust. However the shutdown hook is not guaranteed to execute. If a user closes the app abruptly or the VM crashes, or you click on the little red button on the eclipse console view, the shutdown hook will not run. It is not a good idea to use a shutdown hook to release critical resources (I have seen some code snippets that do this). It might end up not running and cause damage. The shutdown hook will execute only on normal termination or orderly shutdown.
Use the shutdown hook if you would like to do trivial operations with it. You can write code inside the hook that can clean up after the program (say delete a temporary file). Or write a bye bye message. The code inside the hook should not do critical things like release DB connections that your program acquired. Doing something like that is asking for trouble, since this code may never run.
Also keep in mind that hooks run concurrently. Each hook is registered as a Thread with the VM and each Thread will run in parallel with the other hooks. If the hooks synchronize over resources incorrectly you will end up dead locking the application.
The hooks also need to finish up quickly. If they do not, that poses a problem. The application will wait for ever to exit gracefully.
So now you know what shutdown hooks are and how to use them, if you ever need to.
In Summary
- Do not write shutdown hooks to do critical tasks
- Make sure your shut down hooks complete quickly
- Consider using one shutdown hook instead of several. If you decide to use several shutdown hooks, make their activities thread safe.
- Hook code flow should not depend on the method in which the application was shutdown. How an application terminates is never guaranteed.
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4486580
Shutdown hooks don’t work reliably on Windows apps which have a gui.
@Mark Thornton
Thank you for posting that. It might help some one who stumbles upon this.
Hi writer,
Thanks for posting such a informative article.
Well, in the article there is “The shutdown hook will execute only on normal termination or orderly shutdown.”
I have a query, what if there is need to handle such kind of imroper termination situtaion?
In our project we implemnetd a locking system. In this when instance executes it’s look for a text file.
if exist then instance never executes, otherwise creates this text file,
and add the shutdown hook on this for deleting this text file at end of execution.
Can you suggest what would be best way to do this, even when there is improper termination of progra?
Thanks,
Tanzy.
@tanzy
Why not just hold the write lock to this file ? When your app terminates, the lock that it holds will be released, whether it terminates correctly or not, but the file can remain. When the app starts, check if the write lock is held. The exact locking mechanism your application needs, depends on the situation.
This question would receive more responses on a forum. Have you tried one like javaranch.com ?