我正在编写一个Java Web Start应用程序,我发现它已经冻结了。当我进行线程转储时,我可以看到死锁中涉及的两个线程都是Event Dispatch Threads。
当我在本地运行应用程序时,只有一个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)
答案 0 :(得分:2)
我们必须找到一个看起来非常像你的问题。
我们的调查结果: Java Webstart正在触发创建多个EDT线程。如果你开始 你的小程序作为应用程序,只有一个EDT可以防止这个问题。
我们可以在第二次EDT上看到活动,只有当我们玩控制台时 窗口(调整大小/隐藏)。 不断调整大小使问题可以很容易地重现。
经过一些搜索后,我们可以在代码中找到一个在paint方法中调用getGraphics的位置。这触发了一系列调用,这些调用以所有组件的最顶层结束 这似乎与这个控制台共享。
当应用程序和控制台打开并且用户解锁时,可能会发生这种情况,因为所有组件都会同时重新绘制。
希望这会有所帮助。 我对这个神秘的共享组件的任何其他细节感兴趣。
就个人而言,我不会怀疑控制台与主应用程序共享一个可能以这种方式相互锁定的组件。
祝你好运答案 1 :(得分:1)
你是正确的AWT-EventQueue-0
是你的正常事件线程,而AWT-EventQueue-1
是你的应用程序通过Java web start启动时创建的线程。 (实际上,如果您的Web启动应用程序没有显示控制台,您会发现第二个是创建的。)
关于死锁的原因,没有看到两个线程的完整堆栈跟踪是不可能的,但是有一些可能性(估计概率递减的顺序!):