Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Shutdown hook not run

I am new to Java/threads and I inherited something like the following code. It is a command line program that main() only starts 5-6 different kind of threads and exits with ^C. I want to add a shutdown hook to close all threads properly and adapted it the following way.

I added a Shutdown hook and a stopThread() method in all threads (like the one in MyWorker class)

The problem is that when I press ^C I don't see the end message from the Thread's run method. Is this done in the background or is there something wrong with my method. Also, Is there a better pattern I should follow?

Thanks

 public class Main {
     public static MyWorker worker1 = new MyWorker();
     // .. various other threads here

     public static void startThreads() {
         worker1.start();
         // .. start other threads
     }

     public static void stopThreads() {
         worker1.stopThread();
         // .. stop other threads
     }

     public static void main(String[] args)
             throws Exception {

         startThreads();

         // TODO this needs more work (later)

         Runtime.getRuntime().addShutdownHook(new Thread() {
             @Override
             public void run() {
                 try {
                     stopThreads();
                 } catch (Exception exp) {

                 }
             }
         });
     } }

 public class MyWorker extends Thread {
     private volatile boolean stop = false;

     public void stopThread() {
         stop = true;
     }

     public void run() {
         while (!stop) {
             // Do stuff here
         }
         // Print exit message with logger
     } 
}
like image 428
jimkont Avatar asked Nov 28 '22 08:11

jimkont


2 Answers

Shutdown Hooks may not be executed in some cases!

First thing to keep in mind is that it is not guaranteed that shutdown hooks will always run. 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 (http://en.wikipedia.org/wiki/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.

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.

like image 191
Nilesh Jadav Avatar answered Nov 30 '22 22:11

Nilesh Jadav


When you call System.exit() or terminate via a signal, it stop all the existing threads and starts all the shutdown hooks. i.e. all your threads could be dead by the time you hook starts.

Instead of trying to stop threads cleanly, you should ensure resources are closed cleanly.

like image 34
Peter Lawrey Avatar answered Nov 30 '22 22:11

Peter Lawrey