简体   繁体   English

多个事件调度线程导致Java Web Start应用程序出现死锁

[英]Multiple Event Dispatch Threads causing deadlock in Java Web Start app

I am writing a Java Web Start application and I have observed it freezing. 我正在编写一个Java Web Start应用程序,我发现它已经冻结了。 When I do a thread dump, I can see the two threads involved in the deadlock are both Event Dispatch Threads. 当我进行线程转储时,我可以看到死锁中涉及的两个线程都是Event Dispatch Threads。

When I run the app locally, there is only one EDT, but when I download and run through Java Web Start, there is a second one. 当我在本地运行应用程序时,只有一个EDT,但是当我下载并运行Java Web Start时,还有第二个。

Can someone tell me why there is a second EDT, and how can I prevent them deadlocking with each other? 有人能告诉我为什么会有第二个EDT,我怎样才能防止它们彼此陷入僵局?

edit: After monitoring the app using JVisualVM, I believe that the second EDT is responsible for redrawing the java console window. 编辑:使用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)

we just had to find a issue which looks very much like yours. 我们只需找到一个看起来非常像你的问题。

Our findings: Java Webstart is triggering the creation of several EDT Threads. 我们的发现:Java Webstart正在触发创建几个EDT线程。 If you start your applet as application there is only a single EDT which would prevent the problem. 如果您将applet作为应用程序启动,则只有一个EDT可以防止出现此问题。

We could see activity on the second EDT only when we played around with the console window (resizing/ hiding). 只有当我们玩控制台窗口(调整大小/隐藏)时,我们才能在第二个EDT上看到活动。 Resizing constantly made the problem reproducible very easily. 不断调整大小使问题可以很容易地重现。

After a bit of hunting we could find a spot in our code where getGraphics was called within a paint method. 经过一些搜索后,我们可以在代码中找到一个位置,其中getGraphics是在paint方法中调用的。 This triggered a chain of calls ending on the very top of all components which seems to be shared with this console. 这触发了一系列调用,这些调用结束于所有组件的最顶层,似乎与此控制台共享。

It is likely that this happens when the application and the console are open and the pc gets unlocked by its user as all components get redrawn at the same time. 当应用程序和控制台打开并且PC被用户解锁时,可能会发生这种情况,因为所有组件都会同时重新绘制。

Hope this helps. 希望这可以帮助。 I would be interested in any additional detail about this mistery shared component. 我会对这个神秘共享组件的任何其他细节感兴趣。

Personally i would not suspect the console sharing a component with the main application that could lock each other in this way. 就个人而言,我不会怀疑控制台与主应用程序共享一个可能以这种方式相互锁定的组件。

Good luck 祝好运

You are correct that the AWT-EventQueue-0 is your normal event thread and AWT-EventQueue-1 is a thread created when your application is started through Java web start. 你是正确的, AWT-EventQueue-0是你的正常事件线程,而AWT-EventQueue-1是你的应用程序通过Java web start启动时创建的线程。 (Actually, you will find that the second one is created if your web start application doesn't display the console.) (实际上,如果您的Web启动应用程序没有显示控制台,您会发现第二个是创建的。)

As to the cause of the deadlock, it is impossible to say without seeing the full stack trace of the two threads, but there a few possiblities (in estimated decreasing order of probability!): 至于死锁的原因,没有看到两个线程的完整堆栈跟踪是不可能的,但是有一些可能性(估计概率递减顺序!):

  • a bug in your video driver 视频驱动程序中的错误
  • a bug in your code 代码中的错误
  • a bug in the JDK JDK中的一个错误

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM