`

SWT图形界面开发中多线程的使用

阅读更多
一、场景
开发java桌面应用大都会带有图形界面,带有图形界面的java程序一般都会有专门负责图形界面渲染、用户输入事件的UI线程,比如swing中的awt线程,swt/jface中的swt线程。

这里主要说一下swt中关于界面的多线程。
桌面程序开发过程中,难免遇到耗时很长的任务,如果放到UI线程中处理,会有界面假死的感觉,用户体验很不好。常用的解决办法就是为这个耗时的任务开辟一个新线程,放到后台去处理,保证界面操作的流畅;后台任务完成后,图形界面获得通知,做出相应的响应。但这种方法在SWT中如何实现呢?

二、问题
SWT在设计上不支持多线程,就是说在非UI线程中调用UI对象是不允许的,若要访问UI界面上的对象必须通过UI线程来访问。SWT在设计上保证在一个线程中使用,这是出于线程安全的考虑。大家可以深入研究一下这么做的目的,我的理解是SWT需要手动释放资源,不想swing那样使用AGC,所以不像swing那样支持多线程。

如果我们从非UI线程去操作UI界面会有什么结果呢?运行下面的代试一下:
package designer;

import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;

public class MultiThreadTest extends ApplicationWindow {
	Text text;

	public MultiThreadTest() {
		super(null);
	}

	public Control createContents(Composite parent) {
		Shell shell = getShell();
		shell.setText("Where am I?");
		text = new Text(shell, SWT.NONE);
		text.setText("Hello world");
		return parent;
	}

	public static void main(String[] args) {
		MultiThreadTest main = new MultiThreadTest();
		main.setBlockOnOpen(true);
		Task task = new Task(main);
		task.start();
		main.open();
		Display.getCurrent().dispose();
	}
}

class Task extends Thread {
	private MultiThreadTest main;

	public Task(MultiThreadTest main) {
		this.main = main;
	}

	public void run() {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e1) {
		}
		main.text.insert("Task begin...");
		for (int i = 0; i < 50; i++) {
			main.text.insert("processing " + i + " task...");
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
			}
		}
	}
}

正常情况下,应该抛出一个运行时错误:
Exception in thread "Thread-0" org.eclipse.swt.SWTException: Invalid thread access

三、解决方法
Display是突破口。Display作为SWT运行时的核心,管理GUI资源,与OS进行通信。
我们必须为更新GUI的任务开辟一个线程,交由UI线程去调用,而让UI线程调用其他任务的方法是通过Display对象:
http://hi.baidu.com/gridrender/blog/item/447c7d181121950135fa410d.html 写道

Display对象中负责调用其他线程的方法有以下3种:

   ● asyncExec(Runnable runnable):异步启动新的线程。所谓异步就是,UI线程不会等待runnable对象执行结束后再继续进行,就是说UI线程可以和runnable对象所在的线程同时运行。
   ● syncExec(Runnable runnable):同步启动新的线程。所谓同步就是,UI线程会等待runnable对象执行结束后才会继续进行,当runnable对象是耗时大的线程时,尽量不要采用此种方式。另外,对于该种方式创建的线程可通过getSyncThread()方法获得线程对象。
   ● timerExec(int milliseconds,Runnable runnable):指定一段时间再启动新的线程。用此方法创建的线程,将会在指定的时间后再启动线程。当然用此方法创建的线程启动后,与UI线程是异步的。如果指定的时间为负数,将不会按时启动线程。

另外Display对象中,与UI线程相关的方法如下所示:
   ● 获得当前的UI线程对象的方法:getThread(),返回Thread对象。
   ● 使UI线程处于休眠状态:sleep()。
   ● 唤醒UI线程:wake()。

3.1获得Display对象
非UI线程可以通过Display.getDefault()获得。如果之前全局中存在Display对象则直接获得;如果之前没有Display对象存在(如SWT之前没调用Display.getDefault()方法,JFace的ApplicationWindow还没有open()),则该线程编程UI线程。
3.2调用策略
暂把为处理耗时任务而开辟的线程叫做任务线程。有两种策略来处理:一是在触发该任务线程时由Display对象启动任务线程(但是这样相当于耗时的任务在UI线程中运行了,界面还是会假死。);二是任务线程中需要更新界面时,通过Display对象启动包含更新动作的新线程。


四、更好的方法
利用SWT的Action和Contribution。
2
2
分享到:
评论

相关推荐

    java高手真经 光盘源码

    javaswt.zip 19.SWT图形界面开发——Java文本编辑器 javajface.zip 20.SWT增强组件库JFace 第5部分(5个程序包) javaapplet.zip 21.Applet网络组件——电子相册 javanet.zip 22.Java网络编程详解(Socket/UDP...

    Java高手真经(编程基础卷)光盘全部源码 免积分

    javaswt.zip 19.SWT图形界面开发——Java文本编辑器 javajface.zip 20.SWT增强组件库JFace 第5部分(5个程序包) javaapplet.zip 21.Applet网络组件——电子相册 javanet.zip 22.Java网络编程详解(Socket/UDP...

    Java高手真经(编程基础卷)光盘全部源码

    javaswt.zip 19.SWT图形界面开发——Java文本编辑器 javajface.zip 20.SWT增强组件库JFace 第5部分(5个程序包) javaapplet.zip 21.Applet网络组件——电子相册 javanet.zip 22.Java网络编程详解(Socket/UDP实例...

    Eclipse_Swt_Jface_核心应用_部分19

    11.5 多线程程序设计 238 11.6 本章小结 243 第12章 SWT系统资源 244 12.1 系统资源概述 244 12.1.1 什么是系统资源 244 12.1.2 释放资源的原则 245 12.1.3 访问资源的原则 246 12.1.4 何时释放资源 ...

    java基础案例与开发详解案例源码全

    12.1.5 为什么需要多线程309 12.1.6 线程分类309 12.2 线程的生命周期309 12.2.1 线程的状态及转换310 12.2.2 线程睡眠311 12.2.3 线程让步313 12.2.4 线程的加入313 12.3 线程的调度和优先级314 12.4 线程的同步315...

    Eclipse权威开发指南2.pdf

    10.3.2 SWT图形用户界面..... 244 10.3.3 基于添加项的Workbench 用户界面..... 245 10.3.4 IDE扩展..... 245 10.4 实现自己的Workbench... 246 10.4.1 可以在Workbench中 配置什么..... 249 10.4.2 启动并运行...

    Eclipse权威开发指南1.pdf

    10.3.2 SWT图形用户界面..... 244 10.3.3 基于添加项的Workbench 用户界面..... 245 10.3.4 IDE扩展..... 245 10.4 实现自己的Workbench... 246 10.4.1 可以在Workbench中 配置什么..... 249 10.4.2 ...

    Eclipse权威开发指南3.pdf

    10.3.2 SWT图形用户界面..... 244 10.3.3 基于添加项的Workbench 用户界面..... 245 10.3.4 IDE扩展..... 245 10.4 实现自己的Workbench... 246 10.4.1 可以在Workbench中 配置什么..... 249 10.4.2 ...

    JAVA上百实例源码以及开源项目

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    JAVA上百实例源码以及开源项目源代码

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    java源码包2

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    Visual C++ 编程资源大全(源码 窗体)

    (59KB)&lt;END&gt;&lt;br&gt;104,cxysplit.zip 这是一个可以在DialogBox中使用的切分类库。(21KB)&lt;END&gt;&lt;br&gt;105,AutoWnd.zip 自动切分一个视图,并且高亮显示具有输入焦点的视图。(31KB)&lt;END&gt;&lt;br&gt;106,MyWnd.zip 高亮显示...

    java源码包---java 源码 大量 实例

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    java源码包3

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

Global site tag (gtag.js) - Google Analytics