Swing EDT引起的客户端卡死
最近调试程序时发现,点击某个界面时会出现卡死的情况,出现的频率还是比较频繁的。
再次出现卡死的情况后,利用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引起的客户端卡死的更多相关文章
- 《FilthyRichClients》读书笔记(一)-SwingのEDT
<FilthyRichClients>读完了前几个章节,现将我的体会结合工作以来从事Swing桌面开发的经验,对本书的一些重要概念进行一次 分析,对书中的一些遗漏与模糊的地方及时补充,同时 ...
- Rsync客户端卡死的问题查询
简介 某备份系统大量使用rsync来传输文件,但是偶尔会出现rsync客户端在上传数据的时候长时间卡死,本文记录了解决问题的步骤. 本文只涉及rsync客户端中IO相关逻辑,关于rsync的发送算法并 ...
- Swing中耗时任务需要另起新线程,这个新线程中更新GUI的操作仍需由EDT来做(转)
最近调试程序时发现,点击某个界面时会出现卡死的情况,出现的频率还是比较频繁的. 再次出现卡死的情况后,利用jvisualvm查看线程的运行情况,dump操作之后发现线程间出现了死锁:Found one ...
- Java客户端工具选择:HTML?Swing?XML?
整理下面的文章是因为个人觉得写的很好,关于java的客户端了解也并不是太多.看了下面的文章觉得很有必要贴出来,方便自己以后了解java客户端编程. Java软件设计师和管理人员经常会面临这样的难题:在 ...
- Swing中的线程并发处理
理论解释见官方的文档: https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html 一个Swing程序中一般有下面三种 ...
- 10个使用Java最广泛的现实领域
10个使用Java最广泛的现实领域 如果你是一个初学者,刚刚开始学习Java,你可能会想Java有什么用呢?除了Minecraft貌似也看不到其他用Java写的游戏,像Adobe Acrobat和Mi ...
- Unity3D手游开发实践
<腾讯桌球:客户端总结> 本次分享总结,起源于腾讯桌球项目,但是不仅仅限于项目本身.虽然基于Unity3D,很多东西同样适用于Cocos.本文从以下10大点进行阐述: 架构设计 原生插件/ ...
- 原生JS的Ajax技术
1.同步和异步 同步现象:客户端发送请求到服务器端,当服务器返回响应之前,客户端都处于等待 卡死状态 异步现象:客户端发送请求到服务器端,无论服务器是否返回响应,客户端都可以随意做其他事情,不会被卡 ...
- NFS及RPC讲解
导读 NFS(Network File System)即网络文件系统,由Sun公司开发,于1984年向外公布.功能是通过网络让不同的机器.不同的操作系统能够彼此分享个别的数据,让应用程序在客户端通过网 ...
随机推荐
- hdu_2668 Daydream O(n)求最长不重复子串
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2668 Daydream Time Limit: 2000/1000 MS (Java/Others) ...
- the quick brown fox jumps over the lazy dog
THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
- 【django基础补充之URL,视图,模版】
一.url路由配置 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django,对于这个URL调用这段代 ...
- java 静态导入 小结
之前看过静态导入这一块,在编程思想里,但是记不清了,今天搜了下,看到有一个博文写的不错,所以留做备注吧 总结: import static xxx.xxx 和普通导入的区别在于,普通导入是需要通过& ...
- git回退操作
情况一:checkout 当你修改了某个文件,未提交暂存区,回退本次修改 git checkout -- file 情况三:reset 当你的代码,已提交到暂存区,还未提交到远程仓库 git log ...
- 零基础教你写python爬虫
大家都知道python经常被用来做爬虫,用来在互联网上抓取我们需要的信息. 使用Python做爬虫,需要用到一些包: requests urllib BeautifulSoup 等等,关于python ...
- mysql数据库创建、删除数据库
一.创建数据库(默认字符集和排序规则) (1)创建数据库 mysql> CREATE DATABASE my_db1; Query OK, 1 row affected (0.00 se ...
- Lnmp修改php.ini配置
http://www.chenruixuan.com/archives/341.html A-A+ 陈瑞轩2014年5月8日07102 次浏览PHP | 工作 要在lnmp系统里面修改php.ini配 ...
- block一点也不神秘————如何利用block进行回调
我们在开发中常常会用到函数回调,你可以用通知来替代回调,但是大多数时候回调是比通知方便的,所以何乐而不为呢?如果你不知道回调使用的场景,我们来假设一下: 1.我现在玩手机 2.突然手机没有电了 3.我 ...
- linux_DNS
linux其配置文件 : /etc/resolv.conf nameserver 223.5.5.5 nameserver 223.6.6.6 # 这两个解析地址为阿里云解析地址,格式也是这样 什么是 ...