4

我正在编写一个 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)
4

2 回答 2

2

我们只需要找到一个看起来很像你的问题。

我们的发现:Java Webstart 正在触发多个 EDT 线程的创建。如果您将小程序作为应用程序启动,则只有一个 EDT 可以防止该问题。

只有当我们使用控制台窗口(调整大小/隐藏)时,我们才能看到第二个 EDT 上的活动。不断调整大小使问题很容易重现。

经过一番摸索,我们可以在代码中找到一个在绘制方法中调用 getGraphics 的地方。这触发了一系列调用,结束于似乎与此控制台共享的所有组件的最顶部。

当应用程序和控制台打开并且 PC 被用户解锁时,很可能会发生这种情况,因为所有组件同时重绘。

希望这可以帮助。我会对这个神秘的共享组件的任何其他细节感兴趣。

就我个人而言,我不会怀疑控制台与可以以这种方式相互锁定的主应用程序共享一个组件。

祝你好运

于 2013-07-02T19:19:17.217 回答
1

您是正确的,这AWT-EventQueue-0是您的正常事件线程,并且AWT-EventQueue-1是通过 Java web start 启动应用程序时创建的线程。(实际上,如果您的 web 启动应用程序不显示控制台,您会发现创建了第二个。)

至于死锁的原因,如果没有看到两个线程的完整堆栈跟踪就不可能说出来,但是有一些可能性(按概率降序排列!):

  • 视频驱动程序中的错误
  • 您的代码中的错误
  • JDK中的一个错误
于 2013-06-28T09:29:53.110 回答