`
fm2005
  • 浏览: 18929 次
社区版块
存档分类
最新评论

SWT中定时器的一种特殊实现方式/SWT中线程互访时display.asyncExec/display.syncExec...程序死掉无响应的解决办法

 
阅读更多

最近在研究SWT,写了个小例子,涉及到线中的数据互访,如果在一个线程中的触发事性中再去访问另一个线程的数据,会把Invalid thread access的错误。

用SWT提供的display.asyncExec方法,发现其实质根本不是另开一个线程,只是把run方法调用了一次,所以导致调用Thread.sleep时程序就会死掉。

经过查阅资料及baidu和google,找到了解决办法,现总结一下:

1、定时器实现方式,在Main方法中加一个定时器,代码如下:()

2、但有时候并不一定要程序执行时就要定时检测,有时需要外部事情激发这就出现了第2种解决方案,写一个内置类,可以放在事件监听的方法中,然后激发:

3、第二种方法虽好,可是创建了不少对象,对程序优化一下,可以得到更好的一种解决方案(比第二种方法少创建一个对象):

顺便再说一下display.asyncExec和display.syncExec的区别:

SWT组件Diaplay提供syncExec与asyncExec方法,其原型为:syncExec (Runnable runnable),asyncExec (Runnable runnable),Runnable的run方法中可以封装要执行的代码,一般而言是UI相关的代码,如更新组件显示、刷新状态等。Diaplay是和线程关联的,其所在的线程一般称谓UI线程,可以有多个UI线程,每个UI线程一个Diaplay。所有的SWT组件相关代码,必须在UI线程之中执行。

syncExec与asyncExec相同点,都是为了让Runnable封装的代码在指定的Diaplay(比如某个产成Image的diaplay) 相关的UI线程中执行。如:imgCreateDiaplay.asyncExec(runnable)。需要说明的是,当前线程一般是非UI线程,也可以是UI线程(如其它UI相关线程如awt UI线程,和为提高执行效率,多个SWT UI线程之间协作并发执行,甚至调用线程和执行runnable的UI线程是同一个线程)

syncExec与asyncExec不相同点体现在对方法调用线程本身的影响,syncExec阻塞当前线程直到UI线程完成runnable中的代码执行;而asyncExec则直接返回,不等待runnable中代码被执行,但并不是说asyncExec执行的代码一定不在同一个线程中,有些时候是同一个线程,只不过将代码的执行根据需要分成两个部分或多个部分处理。

两者的异同决定了其分别适应不同的场合,一般syncExec适合在需要同步UI更新之后继续执行的代码,asyncExec适合在不便、不能syuncExec的情况下使用。

syncExec适用情况比较简单,以下总结asyncExec的适用情况。

1、非UI线程需要调用在UI线程中调用的组件方法。非UI线程是相对与UI线程来讲的,UI线程准确的讲是diaplay变量所在的线程,因此非UI线程其实是非display所在的线程,其可以是任何其它线程,如UI无关的后台作业处理线程、SWT-AWT共用应用中的awt所在线程、其它 display线程(这种情况比较少,一般应用于服务程序,如大量生成图片的多UI线程,相互之间协调时的调用,如几个UI线程负责地图图片的绘制,然后交给另外一个UI线程做装饰处理);

2、跳出当前UI事件处理,安排后续事件。当前display所在的UI线程,在事件处理过程中,需要在执行完毕之后启动另外一个UI处理过程,可以使用 asyncExec,发起另外一个UI线程处理,结束当前的UI处理。有几种情况下需要这么做:A、当前事件处理必须执行完毕,使应用到达一定的状态之后,做另外的UI处理,但是由于SWT、JFace或其它应用框架的存在,当前事件处理完成之后需要应用框架执行一些其它代码之后才可以执行另外的UI处理,否则会导致状态不一致,界面出错。但是当前事件处理完毕之后,不会出现其它事件来触发需要另外执行的代码,此时可以使用asyncExec,在框架的事件处理序列中插入另外一个事件,在当前事件处理完毕之后的某个时刻(一般很快)来执行;B、定时刷新或其它不是很重要的UI操作,通过 asyncExec执行,不影响重要的UI事件处理。asyncExec所在的事件队列优先级较低。

3、事件比较密集,而且不均衡,有时非常密集,有时不太密集,为了将事件处理均衡处理,使UI线程始终能够应付自如,而不是延迟重要事件的处理、使用户感到界面迟钝现象,将不重要的事件放到低优先级序列中,从而保证用户响应性,界面整体的有效性。

asyncExec使用时需要注意的问题主要在于两个方面。
1、响应及时性。可以认为SWT存在两个事件队列,正常UI事件队列,需异步处理的队列,该队列优先级较低,asyncExec对应于SWT低优先级队列,因此有可能在正常队列事件较多、事件处理较慢的时候,asyncExec相关代码不能及时执行的问题,从而导致响应不够及时;
2、多线程同步问题。假如某段事件处理代码发出多个asyncExec请求,每个asyncExec代码访问同一个变量,假设该变量是整数,第一次发出请求是值为1、第二次为2、第三次为3,所有请求发出,该事件处理完毕时,整数值为5,随后第一次发出的asyncExec请求执行,访问整数变量,此时为 5,而本应该是1,其它几个有类似问题。


当然了,Display也提供了timerExec,可以将其理解为Timer和asyncExec两者的结合,代码在指定时间之后异步执行。

分享到:
评论

相关推荐

    swt线程冲突与解决

    - 在SWT中,可以使用`Display.syncExec(Runnable)`方法来实现同步调用。 - 这种方式适用于需要等待UI操作完成并获取结果的场景。 ```java Display.getDefault().syncExec(new Runnable() { @Override public ...

    SWT并发例子(后台耗时线程)

    在SWT中,我们可以使用`Display.asyncExec`或`Display.syncExec`方法来在事件调度线程中执行代码,而使用`new Thread()`来创建并启动新的后台线程来执行耗时任务。以下是一个基本的示例: ```java Button button = ...

    swt 多线程

    总结来说,SWT的多线程机制是通过Display类提供的`asyncExec`、`syncExec`和`timerExec`方法来实现的,它们允许开发者在不阻塞UI线程的情况下执行后台任务。理解和熟练运用这些方法是构建高效、响应性强的SWT应用的...

    java SWT编写的截图程序

    Java SWT(Standard Widget Toolkit)是Java编程环境中用于创建桌面应用程序的一种图形用户界面(GUI)工具包。它由Eclipse基金会维护,与AWT和Swing不同,SWT直接与操作系统API交互,提供更原生的外观和性能。在这...

    swt源码以及jar

    它是Java应用程序中的一种替代AWT和Swing的GUI工具包,特别适用于开发跨平台的应用程序,因为SWT在各个操作系统上实现了原生的用户界面组件。这个压缩包包含了SWT的源代码和预编译的jar文件,这对于开发者来说是极其...

    swt

    通常,使用Display.asyncExec()和Display.syncExec()方法来确保在正确的线程(即UI线程)中更新界面元素,防止出现线程安全问题。 **学习资源:** 博文链接提到的<https://jose-bing.iteye.com/blog/1264042>是一个...

    SWT综合教程及安装指导

    SWT(Standard Widget Toolkit)是Java编程环境中用于创建图形用户界面(GUI)的一种开源库,它是Eclipse项目的一部分。SWT提供了与操作系统底层更紧密的交互,使得开发出的程序性能更优,外观与操作系统的原生应用...

    基于swt的小软件

    例如,使用`Display.asyncExec`或`Display.syncExec`方法在GUI线程中更新界面,确保界面操作的线程安全。 **Bank子文件** 在"Bank"这个子文件中,很可能是实现了一款与银行相关的模拟软件,可能包括账户管理、交易...

    SWT API 资料

    为了实现异步处理,可以使用`Display.asyncExec`和`Display.syncExec`方法,它们能够在正确的线程上下文中执行回调。 ### 9. 高级特性 SWT还提供了许多高级特性,如拖放支持、打印功能、数据库访问、国际化和本地...

    Graphics Moving Package

    7. **动画框架**:虽然SWT没有内置的动画框架,但开发者可以自定义实现,例如通过使用`Display.syncExec`或`Display.asyncExec`来在 SWT 线程中更新图形状态,实现平滑的动画效果。 8. **布局管理**:SWT 提供了...

    SWT应用的开发实例:没有使用到OSGi

    为了实现程序的逻辑,还需要使用`Thread`或者`Display.asyncExec`、`Display.syncExec`来处理异步任务,确保GUI更新的正确性和响应性。 在没有使用OSGi的情况下,开发者需要自行管理类的加载和依赖关系。这可能意味...

    使用Eclipse RCP进行桌面程序开发

    **Eclipse RCP** (Rich Client Platform) 是一种基于Java的开源框架,用于开发桌面应用程序。自从Eclipse 3.0版本以来,RCP逐渐成为构建高度定制化、功能丰富的桌面应用的标准平台之一。 **快速起步步骤**: 1. **...

    Eclipse插件开发问题

    首先,问题一涉及在Eclipse调试Java应用程序时自定义启动配置界面。Eclipse允许开发者通过扩展点机制来自定义启动配置对话框。在XML配置文件中,`<extension point="org.eclipse.debug.ui.launchConfigurationTabs">...

    一个eclipse的helloworld的插件

    在`run()`方法中,我们可以调用`Display.getDefault().asyncExec()`来确保UI更新在Eclipse的主线程中执行,然后弹出一个对话框显示"Hello World"。 4. **注册动作** 将`HelloWorldAction`类与`plugin.xml`关联,...

Global site tag (gtag.js) - Google Analytics