Java Static-block Shutdown Hook with System.exit
deadlock, java, static
Solution
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.
Problem
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?