Java Swing多线程死锁问题解析+我的另类解决方法

转:在基于Java Swing进行图形界面开发的时分,经常遇到的就是Swing多线程成果。我们可以想想一下,假设需要在一个图形界面上显示很少数据,这些数据是经过长时间、复杂的查询和运算得到的。假设在图形界面的同一个线程中进行查询和运算任务则会导致一段工夫界面处于死机形态,这会给用户带来不良的互动感受。为了解决这个成果,普通会独自启动一个线程进行运算和查询任务,并随时更新图形界面。这时分,另一个成果就出现了,能够不仅没有处理原来偶尔死机成果,还能够导致程序彻底死掉。侥幸的是在JDK中隐藏了一个中缀程序的快捷键,就是CTRL+BREAK,这个快捷键Sun并没有在文档中发布。假设在命令行模式下启动Java程序,然后按CTRL+BREAK键,会得到堆栈的跟踪信息。从这些跟踪信息中就可以知道详细引发死机的位置了。  当一个程序发生死锁的时分,你一定会希望尽快找到缘由并且处理它。这时分,你普通的精力会用在查找引发死锁的位置,另一半的精力会用于对堆栈进行跟踪一确定引发死锁的缘由。但是在Java Swing程序中,你的所有努力能够都是没有价值的。这是由于Java对Swing的多线程编程有一个特殊要求。就是在Swing里,只能在与Swing 相同的线程里对GUI元件进行修正。  也就是说,假设你要执行相似于jLabel1.setText("blabla")代码,必须在 Swing线程中,而不允许在其他线程当中。假设必须在其他线程中修正元件,可以使用相似一下方式处理: SwingUtilities.invokeLater(new Runnable() {public void run() {jLabel1.长生鸟setText("blabla"); }}  invokeLater办法虽然外表有工夫延迟执行含义,但是实际上简直没有任何影响,能够在几毫秒之内就会被执行。另外还有一个 invokeAndWait办法,除非特殊需要,否则简直是不必的。  在不使用invokeLater的状况下,导致刷新成果是可以了解的,但是导致死锁就优点令人匪夷所思了。侥幸的是,不是任何时分都需要调用改办法,这是由于大少数状况下,我们都是在与Swing同一个线程里进行界面更新。例如监听按钮点击事情的ActionListener.actionPerformed办法就是运转在与Swing相同的线程中的。但是假设在回调类中引用了另一个类,并且是不属于AWT/Swing的,那么后果就很难确定了。所以说使用invokeLater应该是最安全的。  需要注意的是,在invokeLater做的任何事情,都会导致Swing线程窗口绘制任务暂停上去,等候invokeLater任务结束。所以不要在 invokeLater进行耗时操作,尽量只执行那些界面绘制相关的任务。可以通过代码重构,将那些与界面更新相关的代码集中起来统一处理。  一个建议是那些在Swing中使用的类进行合理的设计。代码执行前判别是否处于Swing线程当中(使用 SwingUtilities.isEventDispatchThread()办法),假设不是,则需要通过 SwingUtilities.invokeLater(Runnable)执行,否则则直接执行代码。但是这说起来简单,但是实际操作会遇到很多困难。

我的解决方法:比如jLabel1.setText("blabla")这个操作我不写在主线程(main方法的)里面(因为这时候如上所说“死锁”了),我作为构造函数形参写在新开的线程里面,例

   JLabel jLabel1;

   // 构造函数
   public WebServer(int port, JLabel jLabel1) {
    // 设置显示服务器运行信息的文本区
    this.jLabel1 = jLabel1;

在新的线程里面操作即可!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值