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?
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();
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With