Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Static-block Shutdown Hook with System.exit

This code will deadlock:

public class Main {
   static public final Object a = new Object();
   static {
      Runtime.getRuntime().addShutdownHook(new Thread() {
         @Override
         public void run() { if (a == null); }
      });
      System.exit(0);
   }
   static public void main(final String[] args) {}
}

This code will exit normally:

public class Main {
   static public final Object a = new Object();
   static {
      final Object aa = a;
      Runtime.getRuntime().addShutdownHook(new Thread() {
         @Override
         public void run() { if (aa == null); }
      });
      System.exit(0);
   }
   static public void main(final String[] args) {}
}

What is happening?

like image 945
Raffy Avatar asked Feb 16 '10 02:02

Raffy


People also ask

Is it okay to use system exit in Java?

It's common for a script to rely on the exit codes of commands it invokes. If such a command is a Java application, then System. exit is handy for sending this exit code. For example, instead of throwing an exception, we can return an abnormal exit code that can then be interpreted by the calling script.

What is runtime getRuntime () addShutdownHook?

getRuntime(). addShutdownHook(new Thread() { public void run() { System. out. println("Running Shutdown Hook"); } }); will print a Running Shutdown Hook at the time of program termination at any point.


1 Answers

It is important that classes are not accessed concurrently whilst initialising, so a lock is held.

I guess what is happening in the first case is:

  • The main thread holds the initialisation lock for Main.
  • Whilst holding the lock, System.exit blocks as it does not return.
  • The shutdown hook executes.
  • The shutdown tries to access the Main class to read a field, but blocks as the class is initialising.

Hence the deadlock. It's a little clearer if you write if (a == null); as if (Main.a == null);.

In the second case, the value is copied and therefore the shutdown hook does not need to access the Main class.

Moral: Don't mix threads and class initialisation. Gafter and Bloch's Java Puzzlers book has more on this.

like image 149
Tom Hawtin - tackline Avatar answered Oct 16 '22 08:10

Tom Hawtin - tackline