swing SwingWorker
来源:互联网 发布:中国建筑网招聘网络 编辑:程序博客网 时间:2024/05/19 13:59
EDT是啥米呀
在Java中,键盘输入、鼠标点击或者应用程序本身产生的请求会被封装成一个事件,放进一个事件队列中,java.awt.EventQueue对象负责从这个队列中取出事件并派发它们。而EventQueue的派发有一个单独的线程管理,这个线程叫做事件派发线程(Event Dispatch Thread),也就是EDT。此外,Swing的绘制请求也是通过EDT来派发的。
根据以上这两个事实,我们就可以解释刚才demo中发生的事情。当checkbox被选中之后,再双击根结点,触发了以下的程序:
- public void treeExpanded(TreeExpansionEvent event) {
- long handleTime = readHugeData();
- label.setText("处理时间为" + handleTime);
- }
事实上,在demo中是用Thread.sleep()方法来模拟readHugeData这个从数据库中读取大量记录这个阻塞方法。那么在这种情况下,EDT在等待数据库的返回期间是不能接收任何事件(比如键盘输入),也不能处理任何组件的绘制。
解决的方法是什么呢?很容易想到,把耗时的方法从EDT中剥离出来,放到单独的工作线程中执行。例如下面这样:
- public void treeExpanded(TreeExpansionEvent event) {
- new Thread(new Runnable() {
- public void run() {
- long handleTime = readHugeData();
- label.setText("处理时间为" + handleTime);
- }
- }).start();
- }
很遗憾,这段代码违反了Swing的单线程原则:即没有在EDT上,而是在工作线程里修改这个label的状态。根据SUN的说法,在测试时可能没问题,但死锁可能随时出现,而且多半发生在给老板演示的时候:>
在SwingWorker出现之前的解决方法是javax.swing.SwingUtilities类的invokeLater方法。在上面的代码片断中,只需将更新label状态的工作封装成一个Runnable的示例,然后作为参数传递给invokeLater()就好了:
- public void treeExpanded(TreeExpansionEvent event) {
- new Thread(new Runnable() {
- public void run() {
- final long handleTime = readHugeData();
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- label.setText("处理时间为" + handleTime);
- }
- });
- }
- }).start();
- }
这样就可以保证demo可以平稳和正确地运行了,但是,要创建好多匿名的Runnable,导致代码难于阅读和维护。为了简化与EDT的交互,SwingWorker登场了。
SwingWorker入门
这个demo中涉及的只是SwingWorker最基础的东东,所以不必担心。看看如何使用把:
- public void treeExpanded(TreeExpansionEvent event) {
- new SwingWorker<Long, Void>() {
- @Override
- protected Long doInBackground() {
- return readHugeData();
- }
- @Override
- protected void done() {
- label.setText("处理时间为" + get());
- }
- }.execute();
- }
我们把耗时阻塞任务放到doInBackground()方法中,更新组件状态的任务放到done()方法中。当任务完成后,SwingWorder自动调用EDT中的done()方法。此外在done()方法中,可以调用get()方法获取doInBackground()方法的返回值,在demo中这个返回值是任务处理时长。好了,SwingWorker就讲到这里了。什么,那个new SwingWorker<Long, Void>()中第二个泛型类型Void是啥意思?请参考Improve Application Performance With SwingWorker in Java SE 6 这篇牛文。
- swing SwingWorker
- Multithreading in swing with SwingWorker
- Swing线程--工作者线程和SwingWorker
- Swing中的并发-使用SwingWorker线程模式
- Swing中的并发-使用SwingWorker线程模式
- SwingWorker
- SwingWorker
- SwingWorker
- SwingWorker,多线程开发swing必备类,很多时候不用它界面会挂掉
- Java Swing编程中需要注意的线程调度及SwingWorker的用法
- about SwingWorker.....
- swingworker笔记
- java SwingWorker
- java-swingworker
- swingworker--Simple Background Tasks
- 使用SwingWorker之一
- 使用SwingWorker之二
- 使用SwingWorker之三
- 复制一个表的所有数据到另外一个表中
- 大型2D网游,全套源码及工具
- 遇到不支持的oracle数据类型101
- 初探DeepEarth控件
- 揭露Boost::typeof的实现阴谋
- swing SwingWorker
- 项目随笔
- 第一个Spring程序
- 微软CodeDom模型学习笔记(一)
- Improve Application Performance With SwingWorker in Java SE 6
- dajihoa
- linux 2.6源代码情景分析笔记之进程1
- DirectX 开发骨骼动画 心得 D3DXPlaneIntersectLine 函数
- 用Qt开发Web和本地混合的应用