Swing 应用程序中的线程和死锁 [英] Threading and deadlock in Swing application

查看:37
本文介绍了Swing 应用程序中的线程和死锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在维护的 Swing 应用程序中遇到了死锁,虽然我有一个看起来可行的解决方法,但我不确定我是否理解我在做什么,并且没有隐藏竞争条件稍后可能会再次弹出.

I'm getting a deadlock in the Swing application I maintain, and although I have a workaround that appears to work, I'm not sure that I have understood what I am doing and haven't just hidden a race condition that may pop up again later.

线程跟踪显示两个线程 AWT-EventQueue-0 和 AWT-EventQueue-1 之间发生了死锁.我的第一个问题是,如果这些中的任何一个是臭名昭著的事件调度线程.两个线程的堆栈跟踪底部都有以下内容:

A thread trace shows the deadlock is occurring between two threads, AWT-EventQueue-0 and AWT-EventQueue-1. My first question is which if either of these is the infamous Event Dispatching Thread. Both threads have the following at the bottom of their stack trace:

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

我认为问题的根源在于应用程序类将域数据与图形组件混合在一起,在这种情况下,两个线程都试图锁定 java.awt.Component$AWTTreeLock 和一个我自己的对象(比如 X).我的解决方法是在 X 被锁定的地方使用 SwingUtilities.invokeLater(),即使这已经在 EDT 上.根据 Javadoc,这意味着调用推迟到所有待处理事件都处理完毕".但是,我不太确定这是否真的是一个解决方案,无论如何我都不清楚为什么似乎有两个 EDT.

I think the root of the problem is that the application classes mix domain data with graphical components, and in this case both threads are trying to lock both a java.awt.Component$AWTTreeLock and one of my own objects (say X). My workaround is to use SwingUtilities.invokeLater() in one place where X is locked, even though this is already on the EDT. According to the Javadoc this means the call "deferred until all pending events have been processed". However, I'm not quite sure that this is really a solution, and in any case I'm unclear why there seem to be two EDTs.

谁能解释一下这是怎么回事?我可以尝试提供代码的简化版本,但我可能需要一段时间来编辑不相关的并发症.

Can anyone explain what is going on? I can try to provide a cut-down version of the code but it may take me a while to edit out the irrelevant complications.

推荐答案

感谢 Yishai 为我指明了正确的方向.应用程序正在实例化它自己的 java.awt.EventQueue 子类,并使用 Toolkit.getDefaultToolkit().getSystemEventQueue().push(newQueue) 替换原始队列.原始队列必须仍在其线程 AWT-EventQueue-0 上处理任务,同时事件开始到达线程 AWT-EventQueue-1 上的新队列>,导致死锁.

Thanks to Yishai for pointing me in the right direction. The application is instantiating its own subclass of java.awt.EventQueue and using Toolkit.getDefaultToolkit().getSystemEventQueue().push(newQueue) to replace the original queue. The original queue must still be processing a task on its thread, AWT-EventQueue-0 at the same time as events start arriving in the new queue on thread AWT-EventQueue-1, resulting in deadlock.

这篇关于Swing 应用程序中的线程和死锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆