AWT-EventQueue не выходит из Unsafe.park

Мы создаем приложение, которое работает с несколькими AppContexts. Теперь, когда один 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 просто отлично. Я просыпаюсь на пользовательских событиях и перерисовываю графический интерфейс. Теперь, после создания и удаления другого 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 не просыпается от метода park при событиях GUI. Как этот механизм вообще работает? Кто отвечает за создание событий Swing и пробуждение EventQueue? Eclipse показывает только один другой поток (DestroyJavaVM).

Я застрял. Я не знаю, где искать. Любые намеки, в каком направлении расследовать, будут высоко оценены.

2 ответа

Решение

Оказывается, проблема была сделана дома. Мы запускаем различные клиентские приложения внутри нашей JVM, для каждого из которых мы создаем собственный AppContext. Чтобы предотвратить утечки памяти, после завершения клиентского приложения мы гарантируем, что EventDispatchThread не имеет пользовательского EventQueue. Поэтому мы сбрасываем его на значение по умолчанию. И у нас там была ошибка, такая, что EventQueue оставшегося EventDispatchThread также сбрасывается, что приводит к вышеуказанной ошибке.

Я понятия не имею о вашей реальной проблеме (если под AppContext вы имеете в виду sun.awt.AppContext, то вам не следует использовать пакеты Sun...), но я могу ответить на ваш вопрос.

Как этот механизм вообще работает? Кто отвечает за создание событий Swing и пробуждение EventQueue? Eclipse показывает только один другой поток (DestroyJavaVM).

В каждом приложении Java много потоков. Даже в приложении "hello world" есть много потоков ("Финализатор", "Монитор Ctrl-Break" и т. Д.), И в каждом приложении Swing есть несколько дополнительных потоков (EDT, "Java2D Disposer", "AWT-Windows" и т. Д.)..). "AWT-Windows" - это поток, который опрашивает события из ОС (по крайней мере, в Windows) и "пробуждает" EDT. Смотрите это: Что такое поток AWT-Windows?

Также смотрите это: Получить список всех потоков, работающих в настоящее время в Java

Другие вопросы по тегам