Adding a ShutdownHook to a Java Program to Enable Clean Exit on CTRL-C

Often times I will be building a Java program that will either be run from a command-line or as a system service.  In most cases, during development, I’ll be running it directly from the command-line and will want to kill it by pressing control c on the keyboard.

When I do that I want to make sure that my program cleanly exits, closing any open files, socket connections, database connects, or what have you.

To do so, you must invoke the addShutdownHook(Thread) method on the Runtime.getRuntime() instance for a given process.

Following is a quick how-to on setting that up.

You need the following 4 things:

  1. The class that you want to be able to shutdown cleanly, we will call this the Parent.
  2. A class that extends Thread, we will call this the ShutdownThread class.  This class will call a method in the Parent
  3. An interface that the Parent will implement, called the ShutdownInterface.
  4. The invocation of the Runtime.getRuntime().addShutdownHook(ShutdownInstance) in the Parent.

The classes:

/** ***************************************************
 *
 * The ShutdownInterface
 */


public interface IShutdownThreadParent {
    public void shutdown();
}


/** ***************************************************
 *
 * The ShutdownThread
 */


public class ShutdownThread extends Thread {

    private IShutdownThreadParent mShutdownThreadParent;

    public ShutdownThread(IShutdownThreadParent mShutdownThreadParent) {
        this.mShutdownThreadParent = mShutdownThreadParent;
    }

    @Override
    public void run() {
        this.mShutdownThreadParent.shutdown();
    }
}

 /** ***************************************************
 *
 * The Parent
 */

public class Parent implements IShutdownThreadParent{

    private  ShutdownThread fShutdownThread;

    public Parent() {
        // Instantiate a new ShutdownThread instance and invoke the addShutdownHook method.
        fShutdownThread = new ShutdownThread(this);
        Runtime.getRuntime().addShutdownHook(fShutdownThread);
    }

    @Override
    public void shutdown() {
        // code to cleanly shutdown your Parent instance.
    }

    public static void main(String[] args) {
        Parent parent = new Parent();
    }
}

When instantiated the Parent class instantiates a new ShutdownThread instance, passing it a reference to itself.  The Parent class then invokes the addShutdownHook() method passing it the reference to the ShudownThread instance.

When CTRL-C is pressed on the keyboard, the JVM will invoke the run method in the ShutdownThread class which will then invoke the shutdown() method in the parent class enabling you to cleanly exit before the JVM exits.

Leave a Reply