小编典典

Swing应用程序中的线程和死锁

java

我在维护的Swing应用程序中遇到了僵局,尽管我有一个可行的解决方法,但我不确定我是否了解自己在做什么,还没有隐藏可能弹出的竞争条件稍后再试。

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

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

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

谁能解释发生了什么?我可以尝试提供该代码的简化版本,但可能要花一些时间才能编辑出无关紧要的并发症。


阅读 220

收藏
2020-11-26

共1个答案

小编典典

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

2020-11-26