javamultithreadingswingdeadlockawt-eventqueue

AWT-EventQueue not waking from Unsafe.park


We create an application that runs with several AppContexts. Now when one AppContext gets disposed, suddenly the remaining AWT-EventQueue doesn't get waked up on Swing Events anymore.

So when I start the application and just have one EventQueue, the thread dump looks like the following:

"AWT-EventQueue-0" prio=5 tid=0x00007fe976a49800 nid=0xf003 waiting on condition [0x000000011ca5d000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for  <0x00000007c2644870> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
at java.awt.EventQueue.getNextEvent(EventQueue.java:543)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

This EventQueue is just fine. I wakes up on user events and rerenders the GUI. Now after creating and disposing a different AppContext, the thread dump looks like the following:

"AWT-EventQueue-0" prio=5 tid=0x00007fe976a49800 nid=0xf003 waiting on condition [0x000000011ca5d000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for  <0x0000000740f41b80> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
at java.awt.EventQueue.getNextEvent(EventQueue.java:543)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

As one can see it is the same thread dump (except for the ConditionObject) and yet the GUI becomes unresponsive as the EventQueue doesn't wake up from the park method on GUI events. How does that mechanism even work? Who is responsible for creating the Swing Events and waking the EventQueue? Eclipse shows only one other thread (DestroyJavaVM).

I am stuck. I don't know where to look. Any hints in what direction to investigate would be highly appreciated.


Solution

  • Turns out the problem was home made. We run different client applications inside our JVM, for each of which we generate a custom AppContext. To prevent memory leaks, after termination of the client application, we ensure that the EventDispatchThread has no custom EventQueue. So we reset it to the default. And we had an error there, such that the EventQueue of the remaining EventDispatchThread gets also reset, resulting in the above error.