2

我们创建一个使用多个 AppContext 运行的应用程序。现在,当一个 AppContext 被释放时,突然剩余的 AWT-EventQueue 不再被 Swing 事件唤醒。

因此,当我启动应用程序并且只有一个 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 除外),但由于 EventQueue 没有从 GUI 事件的 park 方法中唤醒,所以 GUI 变得无响应。这种机制是如何运作的?谁负责创建 Swing 事件和唤醒 EventQueue?Eclipse 仅显示另一个线程 (DestroyJavaVM)。

我被困住了。我不知道在哪里看。任何有关调查方向的提示都将受到高度赞赏。

4

2 回答 2

1

I have no idea about your real problem (if by AppContext you mean sun.awt.AppContext, then you shouldn't really use sun packages...), but I can answer your question.

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

There are lots of threads in every Java application. Even in a "hello world" app there are many threads ("Finalizer", "Monitor Ctrl-Break" etc), and in every swing app there are several additional threads (EDT, "Java2D Disposer", "AWT-Windows" etc.). "AWT-Windows" is the thread that polls the events from the OS (at least on Windows) and "wakes up" the EDT. See this: What is AWT-Windows thread?

Also see this: Get a List of all Threads currently running in Java

于 2015-03-03T10:44:56.640 回答
0

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

于 2015-03-16T12:34:26.473 回答