最近调试程序时发现,点击某个界面时会出现卡死的情况,出现的频率还是比较频繁的。

再次出现卡死的情况后,利用jvisualvm查看线程的运行情况,dump操作之后发现线程间出现了死锁:

Found one Java-level deadlock:
=============================
"Thread-122":
  waiting to lock monitor 0x484052e4 (object 0x1af2bb08, a com.raisecom.ems.templet.client.panel.SnmpTablePanel),
  which is held by "AWT-EventQueue-0"
"AWT-EventQueue-0":
  waiting to lock monitor 0x4861c81c (object 0x180d5950, a java.awt.Component$AWTTreeLock),
  which is held by "Thread-122“

再在线程堆栈中查看根源的线程及方法,找到如下的代码:

public void onSelectionChanged(SelectionChangedEvent e)
 {
  Object source = e.getSource();
  if (source instanceof AbstractMenuTreePanel)
  {
   ///单起个线程处理显示
   Thread thread = new Thread(){
    public void run()
    {

if(!"".equals(DemarcationConfigCenterView.this.m_ProVer))
            refreshConfigPanel2();            
     else

refreshConfigPanel();
       }    
     }
    }
   };
   thread.start();
  }

EDT以外的线程中更新界面都需要SwingUtilities.invokeLater,修改代码:

public void onSelectionChanged(SelectionChangedEvent e)
 {
  Object source = e.getSource();
  if (source instanceof AbstractMenuTreePanel)
  {
   ///单起个线程处理显示
   Thread thread = new Thread(){
    public void run()
    {

if(!"".equals(DemarcationConfigCenterView.this.m_ProVer))
      SwingUtilities.invokeLater(new Runnable() {       
       public void run() {
        refreshConfigPanel2();
       }
      });             
     else{
      SwingUtilities.invokeLater(new Runnable() {       
       public void run() {
        refreshConfigPanel();
       }
      });      
     }
    }
   };
   thread.start();
  }测试没有发生客户端卡死的现象了。

当swing界面程序启动的时候,会启动3个进程,
1、主线程
2、系统工具包线程:负责捕获操作系统事件,然后将事件转换成swing的事件,然后发送到事件派发线程EDT
3、事件派发线程(EDT):将事件派发到各个组件,并负责调用绘制方法更新界面

所有的事件,例如键盘,鼠标事件,都会由工具包线程转换成swing事件,然后放到事件队列EventQueue中,而这个EventQueue的派发机制是由EDT来管理的。

所以任何修改组件状态的方法都应该在EDT中执行,包括构造方法。Swing这样的构造原理经常会造成的情况就是,在EDT中执行长时间的事件,使EDT不能及时响应更新界面的事件,就是所说的界面卡住,这种不光是新手就是比较熟练的程序员也会犯的一个错误。所以必须避免在EDT中执行长时间的操作,而避免的方法就是多线程,启动另外的线程来处理冗长的操作,比如操作数据库,读写文件等,在这过程中可能要更新界面来给用户以提示,比如显示一个进度条,过一段事件更新一下界面,但是在EDT以外的线程中更新界面都是无效的,这在前面已经说过,要更新界面就要将对界面的更新操作放到EDT中,但是事件又是在另外的线程中执行的,要解决这个问题就要使用SwingUtilities提供的一个方法了 invokeLater,
public void actionPerformed(ActionEvent e){
    new Thread(new Runnable(){
            //do something
            SwingUtilities.invokeLater(new Runnable(){
                pulic void run(){
                    //update the GUI
                }    
        });
    }).start;
}
这个方法的作用就是将一个更新界面的任务放到EDT中,EDT会在适当的时候进行调用以更新界面。invokeLater负责创建一个含有Runnable的特定事件,并让其在EDT中排队等待调用,当被调用时就会运行Runnable中的run方法进行派发。

Swing EDT引起的客户端卡死的更多相关文章

  1. 《FilthyRichClients》读书笔记(一)-SwingのEDT

    <FilthyRichClients>读完了前几个章节,现将我的体会结合工作以来从事Swing桌面开发的经验,对本书的一些重要概念进行一次 分析,对书中的一些遗漏与模糊的地方及时补充,同时 ...

  2. Rsync客户端卡死的问题查询

    简介 某备份系统大量使用rsync来传输文件,但是偶尔会出现rsync客户端在上传数据的时候长时间卡死,本文记录了解决问题的步骤. 本文只涉及rsync客户端中IO相关逻辑,关于rsync的发送算法并 ...

  3. Swing中耗时任务需要另起新线程,这个新线程中更新GUI的操作仍需由EDT来做(转)

    最近调试程序时发现,点击某个界面时会出现卡死的情况,出现的频率还是比较频繁的. 再次出现卡死的情况后,利用jvisualvm查看线程的运行情况,dump操作之后发现线程间出现了死锁:Found one ...

  4. Java客户端工具选择:HTML?Swing?XML?

    整理下面的文章是因为个人觉得写的很好,关于java的客户端了解也并不是太多.看了下面的文章觉得很有必要贴出来,方便自己以后了解java客户端编程. Java软件设计师和管理人员经常会面临这样的难题:在 ...

  5. Swing中的线程并发处理

    理论解释见官方的文档: https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html 一个Swing程序中一般有下面三种 ...

  6. 10个使用Java最广泛的现实领域

    10个使用Java最广泛的现实领域 如果你是一个初学者,刚刚开始学习Java,你可能会想Java有什么用呢?除了Minecraft貌似也看不到其他用Java写的游戏,像Adobe Acrobat和Mi ...

  7. Unity3D手游开发实践

    <腾讯桌球:客户端总结> 本次分享总结,起源于腾讯桌球项目,但是不仅仅限于项目本身.虽然基于Unity3D,很多东西同样适用于Cocos.本文从以下10大点进行阐述: 架构设计 原生插件/ ...

  8. 原生JS的Ajax技术

    1.同步和异步 同步现象:客户端发送请求到服务器端,当服务器返回响应之前,客户端都处于等待  卡死状态 异步现象:客户端发送请求到服务器端,无论服务器是否返回响应,客户端都可以随意做其他事情,不会被卡 ...

  9. NFS及RPC讲解

    导读 NFS(Network File System)即网络文件系统,由Sun公司开发,于1984年向外公布.功能是通过网络让不同的机器.不同的操作系统能够彼此分享个别的数据,让应用程序在客户端通过网 ...

随机推荐

  1. [51nod1614]刷题计划

    大赛将至,摆在你面前的是n道题目,第 i(1 ≤ i ≤ n) 道题目能提升 ai 点智力值,代码量为 bi KB,无聊值为 ci ,求至少提升m点智力值的情况下,所做题目代码量之和*无聊值之和最小为 ...

  2. opencv+vs配环境

    首先,一定要注意debug和release下配的项目设置是有区分的!!!!!!!!!!! 1.注意自己的电脑是64位还是32位 2.要在环境变量中设置环境变量,环境变量从前向后扫描,用64位环境变量时 ...

  3. HDU--2114

    Calculate S(n) Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. net+Oracle开发过程中遇到的小问题

    最新的项目开始使用Oracle后,5个月之间遇到一些在SqlServer中没有遇到的问题,这里记录并贴上一些常用的解决办法. Oracle相关 一.数据库不同版本还原: 刚开始我们一直使用Oracle ...

  5. GDI绘制时钟效果,与系统时间保持同步,基于Winform

    2018年工作之余,想起来捡起GDI方面的技术,特意在RichCodeBox项目中做了两个示例程序,其中一个就是时钟效果,纯C#开发.这个CSharpQuartz是今天上午抽出一些时间,编写的,算是偷 ...

  6. 复选框之checked属性

    今天无意中看到同事在学习复选框里面的checked属性的应用,当时看了一下,感觉熟悉而又陌生,发现checked属性其实还是挺奇怪的,感觉这里很有必要做一下笔记: 1.html中的checked属性. ...

  7. CSAPP 第二章随笔

    类型转换问题 (1)int -> short 二进制位高位截断,低位保持不变 (2)同类型 unsign -> sign 记住二进制位是不变的 (3)P101页提到的编译器乘法优化问题,一 ...

  8. 邓_phpcms_phpcms授课思路复习

    思路: 一.目前在企业中使用比较多的cms内容管理有如下几种: 1.dedecms 2.phpcms 二.我们选择学习v9版本的phpcms,主要有以下几点原因: 1.基于MVC模式的内容管理系统 2 ...

  9. MyBatis之基于XML的动态SQL

    先说下我的梦想,大学的时候一直想着是能开店卖胡辣汤,到目前依然还是我的梦想,上周一家出版社联系我问我有没有时间可以合作出书,这也是我的梦想之一,想了想还是放弃了,至少觉得目前不行,毕竟工作还不到五年, ...

  10. 04 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之高并发优化

    Github:https://github.com/nnngu 项目源代码:https://github.com/nnngu/nguSeckill 关于并发 并发性上不去是因为当多个线程同时访问一行数 ...