2012-03-20 3 views
2

Я получаю тупик в приложении Swing, которое я поддерживаю, и хотя у меня есть обходное решение, которое, похоже, работает, я не уверен, что я понял, что делаю, и не знаю просто скрытое состояние гонки, которое может появиться позже.Threading and deadlock in Swing application

Трассировка потока показывает, что тупик происходит между двумя потоками, AWT-EventQueue-0 и AWT-EventQueue-1. Мой первый вопрос заключается в том, какой из них является позорным событием Dispatching Thread. Оба потока имеют следующие в нижней части их трассировки стека:

at java.awt.EventDispatchThread.run(EventDispatchThread.java:138) 

Я думаю, что корень проблемы заключается в том, что данные доменные классы приложений смешивания с графическими компонентами, и в этом случае оба потока пытаются заблокировать и a java.awt.Component$AWTTreeLock и один из моих собственных объектов (скажем, X). Моим обходным путем является использование SwingUtilities.invokeLater() в одном месте, где X заблокирован, хотя это уже на EDT. Согласно Javadoc, это означает, что вызов «отложен до тех пор, пока все незавершенные события не будут обработаны». Однако я не совсем уверен, что это действительно решение, и в любом случае я не понимаю, почему, похоже, есть два EDT.

Может ли кто-нибудь объяснить, что происходит? Я могу попытаться предоставить сокращенную версию кода, но мне может потребоваться некоторое время, чтобы отредактировать неуместные осложнения.

+2

Вы открываете модальное диалоговое окно в этом процессе? Или ваш код нажимает новую очередь? – Yishai

+0

А, да! Я должен буду посмотреть, как это работает. Не заменяет ли существующую очередь? Почему это приведет к двум потокам AWT-EventQueue? – Ben

ответ

1

Благодаря Yishai для указания меня в правильном направлении. Приложение создает свой собственный подкласс java.awt.EventQueue и использует Toolkit.getDefaultToolkit().getSystemEventQueue().push(newQueue) для замены исходной очереди. Первоначальная очередь все равно должна обрабатывать задачу в своем потоке, AWT-EventQueue-0, в то время как события начинают прибывать в новую очередь в потоке AWT-EventQueue-1, что приводит к тупиковой ситуации.

0

Вы создаете темы в любом месте? Если да, то рассмотрите использование

http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html

или

http://docs.oracle.com/javase/7/docs/api/javax/swing/Timer.html

вместо которые хорошо работают с Swing.

+0

Нет, явно не создавая никаких новых потоков. Просто инициализация основного потока (некоторые из которых я переместил в EDT с помощью invokeLater) и обработчики событий для компонентов Swing, которые, конечно же, вызываются в EDT. Так и должно быть. – Ben