Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.exit is not thread-safe on Linux?

I've just switched from Oracle JDK 1.6, to Open JDK 1.7.0_03, and I've hit a rather remarkable deadlock on exit:

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 appears that you must call System.exit from the AWT event queue. Is this for real? There is no documentation of a thread requirement in the Sun docs Runtime.exit

I've hit other surprising cases where getting the AWT tree lock is required only on Linux, but this one takes the cake. Is this a bug, or have I just missed something in the documentation?

like image 501
Joshua Smith Avatar asked Apr 04 '13 14:04

Joshua Smith


2 Answers

It depends, the runHooks method will start any hook threads registered through Runtime.addShutdownHook and wait for them to be finished. If any of your hook threads is locking some resources that the AWT event thread is requiring too, they may cause dead lock.

If you have to call System.exit in your AWT event thread,I suggest you call it in another thread like:

 new Thread(){
            public void run() {
                System.exit(0);
            }
   }.start();
like image 67
BlackJoker Avatar answered Oct 04 '22 03:10

BlackJoker


It is impossible to say whether this is a bug in the runtime without knowing more about what the application is doing (ideally, this would take the form of an SSCCE).

For example, the following demonstrates a similar deadlock involving System.exit(). However, it is clearly a bug in the application, 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);
    }
}
like image 22
NPE Avatar answered Oct 04 '22 03:10

NPE