AWT-EventQueue 未从 Unsafe.park 唤醒

AWT-EventQueue not waking from Unsafe.park

我们创建了一个使用多个 AppContext 运行的应用程序。现在,当一个 AppContext 被处理掉时,突然间剩下的 AWT-EventQueue 不再被 Swing Events 唤醒。

所以当我启动应用程序并且只有一个 EventQueue 时,线程转储如下所示:

"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)

这个EventQueue就好了。我唤醒用户事件并重新呈现 GUI。现在,在创建并处理不同的 AppContext 之后,线程转储如下所示:

"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)

如您所见,这是相同的线程转储(ConditionObject 除外),但 GUI 变得无响应,因为 EventQueue 没有从 GUI 事件的 park 方法中唤醒。该机制如何运作?谁负责创建 Swing 事件和唤醒 EventQueue? Eclipse 仅显示一个其他线程 (DestroyJavaVM)。

我卡住了。我不知道去哪里看。任何有关调查方向的提示都将不胜感激。

我不知道你真正的问题(如果 AppContext 你的意思是 sun.awt.AppContext,那么你真的不应该使用 sun 包...),但我可以回答你的问题。

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).

每个 Java 应用程序中都有很多线程。即使在 "hello world" 应用程序中也有许多线程("Finalizer"、"Monitor Ctrl-Break" 等),并且在每个 swing 应用程序中都有几个额外的线程(EDT、"Java2D Disposer"、"AWT-Windows" 等)。 "AWT-Windows" 是从 OS(至少在 Windows)和 "wakes up" EDT 轮询事件的线程。看到这个:What is AWT-Windows thread?

另请参阅:Get a List of all Threads currently running in Java

原来问题出在家里。我们在 JVM 中 运行 不同的客户端应用程序,我们为每个应用程序生成一个自定义 AppContext。为了防止内存泄漏,在客户端应用程序终止后,我们确保 EventDispatchThread 没有自定义 EventQueue。所以我们将其重置为默认值。我们在那里有一个错误,使得剩余的 EventDispatchThread 的 EventQueue 也被重置,导致上述错误。