Несколько потоков отправки событий, вызывающих взаимоблокировку в приложении Java Web Start

Я пишу приложение Java Web Start и заметил, что оно зависает. Когда я делаю дамп потока, я вижу, что два потока, вовлеченных в взаимоблокировку, являются потоками диспетчеризации событий.

Когда я запускаю приложение локально, есть только один EDT, но когда я загружаю и запускаю через Java Web Start, появляется второй.

Может ли кто-нибудь сказать мне, почему существует второй EDT и как я могу предотвратить их взаимоблокировку друг с другом?

редактировать: после мониторинга приложения с помощью JVisualVM я считаю, что второй EDT отвечает за перерисовку окна консоли Java.

Found one Java-level deadlock:
=============================
"AWT-EventQueue-1":
  waiting to lock monitor 0x07e4d8fc (object 0x29c2d950, a java.awt.Component$AWTTreeLock),
  which is held by "AWT-EventQueue-0"
"AWT-EventQueue-0":
  waiting to lock monitor 0x07e4cbfc (object 0x29c294e8, a java.lang.StringBuilder),
  which is held by "AWT-EventQueue-1"


Java stack information for the threads listed above:
===================================================
"AWT-EventQueue-1":
    at java.awt.Window.getOpacity(Unknown Source)
    - waiting to lock <0x29c2d950> (a java.awt.Component$AWTTreeLock)
    at sun.awt.SunToolkit.isContainingTopLevelTranslucent(Unknown Source)
    at sun.awt.windows.WComponentPeer.isAccelCapable(Unknown Source)
    at sun.java2d.d3d.D3DSurfaceData$D3DWindowSurfaceData.restoreSurface(Unknown Source)
    at sun.java2d.d3d.D3DScreenUpdateManager.validate(Unknown Source)
    at sun.java2d.d3d.D3DScreenUpdateManager.createGraphics(Unknown Source)
    at sun.awt.windows.WComponentPeer.getGraphics(Unknown Source)
    at java.awt.Component.getGraphics(Unknown Source)
    at javax.swing.JFrame.getGraphics(Unknown Source)
    at javax.swing.JComponent.safelyGetGraphics(Unknown Source)
    - locked <0x29c294e8> (a java.lang.StringBuilder)
    at javax.swing.RepaintManager$3.run(Unknown Source)
...
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
"AWT-EventQueue-0":
    at javax.swing.JComponent.isComponentObtainingGraphicsFrom(Unknown Source)
    - waiting to lock <0x29c294e8> (a java.lang.StringBuilder)
    at javax.swing.JComponent.getGraphicsInvoked(Unknown Source)
    at javax.swing.JFrame.getGraphics(Unknown Source)
...
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

person birkner    schedule 29.05.2013    source источник
comment
Может ли это быть: stackoverflow.com/questions/ 9795385/   -  person assylias    schedule 29.05.2013
comment
Нет. Я не создаю свой собственный EDT, если вы об этом спрашиваете @assylias.   -  person birkner    schedule 29.05.2013


Ответы (2)


нам просто нужно было найти проблему, которая очень похожа на вашу.

Наши выводы: Java Webstart запускает создание нескольких потоков EDT. Если вы запускаете свой апплет как приложение, существует только один EDT, который предотвратит проблему.

Мы могли видеть активность во втором EDT, только когда мы играли с окном консоли (изменение размера/скрытие). Постоянное изменение размера делало проблему очень легко воспроизводимой.

Немного поискав, мы смогли найти место в нашем коде, где getGraphics вызывается внутри метода рисования. Это вызвало цепочку вызовов, заканчивающихся на самом верху всех компонентов, которые, похоже, используются совместно с этой консолью.

Вполне вероятно, что это происходит, когда приложение и консоль открыты, а компьютер разблокирован пользователем, поскольку все компоненты перерисовываются одновременно.

Надеюсь это поможет. Мне были бы интересны любые дополнительные подробности об этом совместно используемом компоненте.

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

Удачи

person Thorsten    schedule 02.07.2013

Вы правы в том, что AWT-EventQueue-0 — это ваш обычный поток событий, а AWT-EventQueue-1 — это поток, созданный при запуске вашего приложения через веб-запуск Java. (На самом деле вы обнаружите, что второй создается, если ваше веб-приложение запуска не отображает консоль.)

Что касается причины взаимоблокировки, невозможно сказать, не видя полной трассировки стека двух потоков, но есть несколько возможностей (в порядке убывания вероятности!):

  • ошибка в вашем видеодрайвере
  • ошибка в вашем коде
  • ошибка в JDK
person rxg    schedule 28.06.2013