Java Swing多线程死锁问题解析
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应该是最安全的。
相关文档:
Ubuntu/debian 更改默认Java环境
我的电脑里安装了两个版本的Java,一个是java-6-sun,还有一个是java-gcj
gcj是在JVM非常缓慢的时候诞生的,他可以把Java代码编译成本地代码 ,关于gcj暂且说这么多,回到主题。
修改默认java环境用到命令update-java-alternatives
1、使用update-java-alternatives -l查看目前已经安装 ......
XML 数据格式很难搜索,但是最近随着 XQuery API 的出现,XML 搜索变得非常灵活和简单。对于使用 SAX、DOM、JDOM、JAXP 等处理 XML 文档的 Java™ 程序员来说,工具箱中增加 XQuery API for Java 是一件值得高兴的事。现在 Java 程序员不用再求助于系统调用或者笨拙的 API 就能利用 XQuery 的强大功能了,Sun 提供了一 ......
1. 你需要精通面向对象分析与设计(OOA/OOD)、涉及模式(GOF,J2EEDP)以及综合模式。你应该了解UML,尤其是class、object、interaction以及statediagrams。
2. 你需要学习Java语言的基础知识以及它的核心类库(collections、serialization、streams、networking、multithreading、reflection、event、handling、NIO、localiza ......
0 引言
从控制台中读取数据是一个比较常用的功能,在 JDK 5.0 以前的版本中的实现是比较复杂的,需要手工处理系统的输入流。有意思的是,从 JDK 5.0 版本开始,能从控制台中输入数据的方法每增加一个版本号,就有一种新增的方法,这也增加了选择的种类,可以依据不同的要求来进行选择。下面来看一下 ......
对List的遍历有三种方式
List<A> list = new ArrayList<A>();
list.add(new A());
list.add(new & ......