Friday, October 21, 2011

Shutdown Hook

Sometimes it is necessary to perform some cleanup before your java application shuts down. But problem is user may not always exit properly. User may terminate by pressing Ctrl + C or may simply logoff or shutdown the Operating system while application is still running.

How to ensure that cleanup code executes in such scenario?

Well! Java provides an elegant way to execute cleanup code in the middle of shutdown process. We will discuss it in this article.

Let’s start by understanding what happens when JVM (Java Virtual Machine) shuts down!


JVM Shutdown

The Java virtual machine (JVM) shuts down in response to two kinds of events.
  1. The Java program exits normally, when the last non-daemon thread exits or when the System.exit() method is invoked.
  2. The virtual machine is terminated in response to a user interrupt, such as typing Ctrl + C, or a system-wide event, such as user logoff or system shutdown.
JVM does not shut down immediately. While shutting down JVM initializes its “Shutdown sequence”. Shutdown sequence consists of two phases.

Phase I:           All registered shutdown hooks, if any, are started in some unspecified order and allowed to run concurrently until they finish.
Phase II:         In the second phase all uninvoked finalizers are run if finalization-on-exit has been enabled. Once this is done the virtual machine halts.
We are interested here in Phase I. Since Java allows us to register our own shutdown hook, we can add our clean up code in shutdown hook.

How to create a Shutdown hook?

Shutdown hook is a Java thread registered with JVM by using addShutdownHook method of the java.lang.Runtime class.

public void addShutdownHook(Thread hook);

Steps to create:

1. Create a class that extends Thread.
2. Put your cleanup code in run method.
3. Register the instance of this class as a shutdown hook by using addShutDownHook method.

    The virtual machine will start and run your shutdown hook when it runs its shutdown sequence.Example code below shows how to create and register Shutdown Hook.

package com;
public class ShutDownHookTest {

 public static void main(String[] args) {
  System.out.println("Main Thread Started!");
  
  //Create Instance of Shutdown Hook.
  MyShutDownHook inst = new MyShutDownHook();
  
  //Register Shutdown Hook with JVM
  Runtime.getRuntime().addShutdownHook(inst);
  
  System.exit(0);
  
  // This code will never get executed
  System.out.println("Main Thread Stops !");
 }
 

}
class MyShutDownHook extends Thread{
 public void run(){
  // The Clean code to run before shut down can go here !
  System.out.println("In Shut Down Hook.");
 }
}





In this above example we have created our own thread class MyShutDownHook and registered its instance using addShutdownHook method. 
If you look at the output of the code, you can see that MyShutDownHook thread is executed just before exiting the code.

This is Great !! But do this code will really work if user presses Ctrl + C.
Let's find it out.

Ctrl + C and Shutdown Hook 


We will modify above code slightly to see what happens with Ctrl + C. To do that we will put infinite while loop in our code. See the code below.
package com;

public class ShutDownHookTest {

 public static void main(String[] args) {
  System.out.println("Lets wait Forever (Press Ctrl+ C to end)!");
  //Create Instance of Shutdown Hook.
  MyShutDownHook inst = new MyShutDownHook();
  //Register Shutdown Hook with JVM
  Runtime.getRuntime().addShutdownHook(inst);
  
  while(true);
 }
}

class MyShutDownHook extends Thread{
 public void run(){
  // The Clean code to run before shut down can go here !
  System.out.println("In Shut Down Hook.");
 }
}

If we run this program, program will wait forever unless user presses Ctrl + C. When user presses it we see
"Shutdown Hook" getting executed before terminating !! Yes , Shutdown Hook works !






What if shutdown hook itself hangs ?

In above code we put infinite loop in Main thread of execution and will be able to terminate it with Ctrl + C. Can we put it in Shutdown hook itself ? Let's try it out !
class MyShutDownHook extends Thread{
 public void run(){
  System.out.println("In Shut Down Hook.");
  
  while(true); // This is Dangerous! 
 }
}

Modify the run method in above example to include while(true) and you will found that the program will hang indefinitely. Only way to terminate this is using Task Manager.!

Precautions !


Shutdown hooks run at a delicate time in the life cycle of a virtual machine and should therefore be coded defensively.

Shutdown hooks must be written to be thread-safe.

Shutdown hooks must avoid deadlocks.

Shutdown hooks should also finish their work quickly.When a program invokes exit 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.

2 comments:

Vinayak Deshmukh said...

Nice info sir.. would definitely like to try this!!.. Thnx for sharing ..

Ashutosh said...

Sweet and SHort ... Easy to Understand.. understandable Language ...(tough this isnt studied before!!)