Is system.exit not thread safe on Linux?

I just migrated from Oracle JDK 1.6 to open JDK 1.7.0_03, and I hit a pretty wonderful deadlock on exiting:

java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.lang.Thread.join(Thread.java:1258) - locked <0x8608dda0> (a sun.awt.X11.XToolkit$1$1) at java.lang.Thread.join(Thread.java:1332) at java.lang.ApplicationShutdownHooks.runHooks(ApplicationShutdownHooks.java:106) at java.lang.ApplicationShutdownHooks$1.run(ApplicationShutdownHooks.java:46) at java.lang.Shutdown.runHooks(Shutdown.java:123) at java.lang.Shutdown.sequence(Shutdown.java:167) at java.lang.Shutdown.exit(Shutdown.java:212) - locked <0x8603df28> (a java.lang.Class for java.lang.Shutdown) at java.lang.Runtime.exit(Runtime.java:107) at java.lang.System.exit(System.java:960) 

It looks like you should call System.exit from the AWT event queue. Is this for real? No Stream Requirement Documentation in Sun Runtime.exit Docs

I came across other unexpected cases when getting an AWT tree lock is only required on Linux, but it takes a cake. Is this a mistake or am I just missing something in the documentation?

+6
source share
2 answers

It depends on whether the runHooks method starts any hanging threads registered through Runtime.addShutdownHook and wait for them to complete. If any of your hook threads blocks some resources that also require an AWT event stream, they can cause deadlock.

If you need to call System.exit in an AWT event stream, I suggest you call it in another stream, for example:

  new Thread(){ public void run() { System.exit(0); } }.start(); 
+1
source

It is impossible to say if this is a runtime error without knowing more about what the application is doing (ideally it would look like SSCCE ).

For example, the following example demonstrates a similar deadlock involving System.exit() . However, this is clearly an error in the application, and not in System.exit() :

 public class OhNo { final static Object lock = new Object(); public static void main(String[] args) { new Thread(new Runnable() { public void run() { synchronized (lock) { for (;;) { } } } }).start(); Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { public void run() { synchronized (lock) { System.out.println("in shutdown hook"); } } })); System.out.println("about to call System.exit()"); System.exit(0); } } 
+1
source

All Articles