设为首页 加入收藏

TOP

Java Swing多线程死锁问题解析
2014-11-24 02:58:07 来源: 作者: 【 】 浏览:0
Tags:Java Swing 线程 问题 解析

当一个程序产生死锁的时候,你一定会希望尽快找到原因并且解决它。这时候,你一般的精力会用在查找引发死锁的位置,另一半的精力会用于对堆栈进行跟踪一确定引发死锁的原因。但是在Java Swing程序中,你的所有努力可能都是没有价值的。这是因为Java对Swing的多线程编程有一个特殊要求。就是在Swing里,只能在与Swing相同的线程里对GUI元件进行修改。


也就是说,如果你要执行类似于jLabel1.setText("blabla")代码,必须在Swing线程中,而不允许在其他线程当中。如果必须在其他线程中修改元件,可以使用类似一下方式解决:


invokeLater方法虽然表面有时间延迟执行含义,但是实际上几乎没有任何影响,可能在几毫秒之内就会被执行。另外还有一个invokeAndWait方法,除非特殊需要,否则几乎是不用的。


在不使用invokeLater的情况下,导致刷新问题是可以理解的,但是导致死锁就优点令人匪夷所思了。幸运的是,不是任何时候都需要调用改方法,这是因为大多数情况下,我们都是在与Swing同一个线程里进行界面更新。例如监听按钮点击事件的ActionListener.actionPerformed方法就是运行在与Swing相同的线程中的。但是如果在回调类中引用了另一个类,并且是不属于AWT/Swing的,那么结果就很难确定了。所以说使用invokeLater应该是最安全的。


需要注意的是,在invokeLater做的任何事情,都会导致Swing线程窗口绘制工作暂停下来,等候invokeLater工作结束。所以不要在invokeLater进行耗时操作,尽量只执行那些界面绘制相关的工作。可以通过代码重构,将那些与界面更新相关的代码集中起来统一处理。


一个建议是那些在Swing中使用的类进行合理的设计。代码执行前判断是否处于Swing线程当中(使用SwingUtilities.isEventDispatchThread()方法),如果不是,则需要通过SwingUtilities.invokeLater(Runnable)执行,否则则直接执行代码。但是这说起来简单,但是实际操作会遇到很多困难。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Ubuntu10.0.4下CyanogenMod编译环.. 下一篇Linux运行fortran程序 出现段错误..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: