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

时间:2012-03-20 21:37:53

标签: java swing thread-safety

我在我维护的Swing应用程序中遇到了僵局,虽然我有一个似乎有用的解决方法,但我不确定我是否理解了我在做什么并且不仅仅隐藏了一个竞争条件可能会在以后再次出现。

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

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

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

有谁可以解释发生了什么?我可以尝试提供代码的简化版本,但可能需要一段时间才能编辑出无关紧要的复杂情况。

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

您是否在任何地方创建线程?如果是,请考虑使用

http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html

http://docs.oracle.com/javase/7/docs/api/javax/swing/Timer.html

相反,它适用于Swing。