`
woniu1983
  • 浏览: 167513 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

SWT 多线程编程中发现的一些问题

    博客分类:
  • SWT
阅读更多
   浴兰节已过,粽叶留香, 借苏东坡词为祭

         
浣溪沙   苏轼
轻汗微微透碧纨。明朝端午浴芳兰。流香涨腻满晴川。
彩线轻缠红玉臂,小符斜挂绿云鬟。佳人相见一千年。


--------------------分割线在此,谁敢动我--------------------------------------------------------------------------------------------

    之前使用SWT来开发GUI桌面小应用程序,牵涉数据库,报表等等东西,刚开始,关于这方面的经验尚浅,跌跌撞撞的写下去。
  
一.  第一个问题: UI僵住 / UI假死
    程序很快就写出来了(借助了SWT Designer之便,呵呵),可惜运行时老是感觉怪怪的,不是很舒服,哪里不舒服也说不上来,后来多运行几遍才发现问题:
    每次连接数据库,导出报表的时候,UI就僵住了,点两下,程序就华丽丽地“没有响应”了。

    到这时俺这么傻大概也明白了:
    UI操作和数据库查询都在UI线程里,而数据库执行查询的时间太长,这个UI线程假死了。

   原因明白,解决方法也就出来了:
    分开UI线程和逻辑处理线程(比较费时间的运算,例如:数据库查询)。

   不废话上Sample Code (俺只上简要代码,对不住兄弟们了,大家都懂的):

Thread thread = new Thread(new Runnable() {

                public void run() {

                   // TODO 长时间的运算
                   while (!display.isDisposed()) {
                         ...
                         ...     
                         ...         
                   }                

                  };

                };);

 thread.start();


  测试运行:
  连接数据库,查询,导出报表的时候,UI依然可以被拖动(当然,为了防止此时用户再次点击按钮来查询数据库,我们应该将UI上的一些元素disable掉,这个大家也懂的)---------沾沾自喜(福兮祸之所出)

二  Java  OutOfMemory(果不其然,出问题了)
  上面修改后的代码,自以为正确,结果还是出问题了,连续多次导出报表后,我发现UI又死了,这回不是假死,而是真死了----OutOfMemory。
  百思不得其解,于是乎借助Jprofiler工具,发现每导出一次报表,其内存就会增长一次,从2Mb--->60Mb,然后就Runtime Error:OutOfMemory了。
 
  通过Jprofiler的内存分析,可以排除UI的问题因素,所以问题肯定出在连接数据库并导出报表的逻辑处理线程(就是上面new 的Thread)上,应该是线程关闭时不能及时释放资源。

  我仔细查了下,发现导出报表过程中我创建的文件流或者缓冲流等等都正常关闭了,没有占用资源不释放的地方。最后折腾了半天,终于定位到问题点:"静态调用外部类TransformerFactory来解析xml"-----解析时占用的内存在解析后没有立即被释放(原因不是很清楚,难道是DOM的关系???),由于这个原因:每次new Thread导出报表之后资源都得不到立即释放,而且我们知道线程间是不能共享内存的(独占性),于是系统可用内存越来越少,导致最终的OutOfMemory。

解决方案:
    由于不了解TransformerFactory如何释放资源,所以我采用了另外一种折衷方案:仅使用一个全局的Thread(逻辑处理线程)来导出报表,当TransformerFactory多次解析xml时,它最多占用当前逻辑处理线程所分配的内存块,而不会像之前那样每次new Thread并占用一个新的内存块(当然也可以用线程池,我这里一个线程就可以完全满足需求了,故不需要使用线程池)。
   唯一注意点:因为目前仅有一个逻辑处理线程,所以该逻辑处理线程也和UI线程一样,在一开始就被启动并处于监听状态。
private Thread thread;
public static void main(final String[] args) {
    display = Display.getDefault();
    shell = new Shell(display, SWT.DIALOG_TRIM | SWT.MIN | SWT.CLOSE);

    thread = new Thread(new Runnable() {

                public void run() {

                   // TODO 长时间的运算
                   while (!display.isDisposed()) {
                       if ("导出报表按钮被点击") {
                         ...
                         ...     
                         ...
                       }              
                   }
                  };

                };);
    //使线程处于就绪状态
    thread.start();
}


   测试:
      经过多次导出报表的测试,终于发现OK了,长出一口气。

三  UI未操作时,CPU占用率比较高,几乎100%
   上面的代码导出报表是没问题了,但是在不做任何操作时, CPU占用率非常高,几乎100%.立刻判断出:逻辑处理线程出问题了,而且可以肯定是该线程一直处于监听状态所致。Jprofiler也证明了这点。

    解决方法:
      在不点击报表按钮时,让该线程sleep

   
private Thread thread;
public static void main(final String[] args) {
    display = Display.getDefault();
    shell = new Shell(display, SWT.DIALOG_TRIM | SWT.MIN | SWT.CLOSE);

    thread = new Thread(new Runnable() {

                public void run() {

                   // TODO 长时间的运算
                   while (!display.isDisposed()) {
                       if ("导出报表按钮被点击") {
                         ...
                         ...     
                         ...
                       } else {
                          // 如果未点击创建报表按钮,则创建报表的线程Sleep中
	 		              try {
				             Thread.sleep(1000);
			              } catch (final InterruptedException e) {
				             e.printStackTrace();
			               }
                       }             
                   }
                  };

                };);
    //使线程处于就绪状态
    thread.start();
}


   测试:
     总算是OK了, 打开UI不做操作时或者时导出报表完毕之后,CPU的占用率都是0%。
   

-----------
小记:
    虽然只是写了个简单的桌面应用程序,但是依旧可以发现很多问题----不经过完全测试的软件是可怕而且不可信的;
    思考和解决问题也是一种成长------程序员的快乐难道建立在此?

    与大家一起分享和成长。。。
 
  
 

     
2
1
分享到:
评论

相关推荐

    局域网聊天 SWT Java 多线程问题已经解决

    本主题将深入探讨如何利用SWT(Standard Widget Toolkit)和Java来构建一个局域网内的聊天应用,并解决其中涉及的多线程问题。SWT是Eclipse基金会提供的一个开源GUI库,它为Java开发者提供了与操作系统更紧密集成的...

    swt页面后台多线程接受ModBUS协议Socket通讯的数据

    在IT行业中,SWT(Standard Widget Toolkit)是一种用于构建Java GUI应用程序的库,它提供了与本机操作...开发者需要熟悉Java编程,理解SWT的事件处理机制,掌握ModBUS协议的细节,并具备网络编程和多线程编程的经验。

    Eclipse之SWT编程

    在多线程环境中,每个线程可以拥有自己的`Display`实例,而`Display.getCurrent()`方法可帮助获取当前活跃的`Display`实例。 - `Shell`:代表操作系统窗口,分为顶层`Shell`和对话`Shell`两种。前者作为`Display`的...

    使用Eclipse进行SWT编程.pdf

    虽然SWT应用程序有很多优点,但是它也存在一些缺点。首先,SWT应用程序需要JNI访问本地窗口组件(native widgets),这可能会增加应用程序的复杂度。其次,SWT应用程序需要设置好对应的环境变量,否则可能会出现问题...

    使用Eclipse进行SWT编程

    SWT之所以诞生,主要是为了解决Java早期GUI框架中存在的问题。 - **历史背景**:在Java发展的早期阶段,Sun Microsystems推出了AWT(Abstract Windowing Toolkit),这是一个基于本地窗口组件(Native Widgets)的...

    java socket多线程聊天

    总的来说,这个Java Socket多线程聊天软件利用了Java的网络编程能力、多线程特性和SWT GUI库,实现了服务器与多个客户端之间的实时、双向通信,为用户提供了一个实用的在线聊天平台。通过这样的实践,开发者可以深入...

    1初学Java多线程之线程简介.pdf

    下面我将详细介绍Java多线程编程中的一些核心概念和知识点。 首先,提到的“DOS”指的是Distributed Operating System,即分布式操作系统,它在多线程编程中并不是主要讨论的内容,但作为计算机基础知识的补充,...

    全屏的SWT多媒体播放器

    SWT(Standard Widget Toolkit)是Java编程环境中用于创建图形用户界面(GUI)的一种库,它由Eclipse基金会维护。在SWT中,开发者可以构建功能丰富的应用程序,包括多媒体播放器。全屏的SWT多媒体播放器是利用SWT库...

    Java swt完整教程

    - SWT对多线程的支持更好,适合复杂的多线程GUI应用。 - Swing则提供跨平台的一致性,并且拥有丰富的内置组件和事件模型。 3. SWT组件 SWT包括各种常见的GUI组件,如按钮(Button)、文本框(Text)、列表(List...

    SWT深入内幕之消息机制探秘.pdf

    这种方式虽然有效,但在性能上有一定损耗,尤其是在多线程环境中存在一些局限性。 ##### 2. VCL VCL使用了一种称为Thunk技术的方法,这种方法利用函数调用过程中的堆栈机制,巧妙地将对象指针传递给窗口过程。虽然...

    swt源码以及jar

    在多线程方面,SWT提供了一个安全的线程模型,确保所有的UI更新都在主线程(通常称为UI线程或Event Dispatch Thread)中执行。这避免了因多线程操作界面导致的竞态条件和死锁问题。开发者可以通过`Display.syncExec...

    用SWT做界面的定时关机软件

    这个项目是一个典型的Java GUI应用程序示例,结合了SWT库的使用,多线程编程,以及与操作系统的交互,为用户提供了一种方便的定时关机解决方案。通过研究其源代码,开发者可以学习到如何构建类似的应用,并深入了解...

    swt入门学习资料

    在编程时,Display 是 SWT 应用程序的入口点,它负责事件循环和线程间的通信。Shell 是 SWT 界面中的窗口对象,可以有多种样式,如普通窗口或对话框。Widgets 是 SWT 中的具体控件,如按钮、文本框等,它们通过 ...

    swt64位和32位jar包4.3版本可用

    SWT(Standard Widget Toolkit)是Java编程环境中一个用于创建图形用户界面(GUI)的开源库。它是Eclipse项目的一部分,提供了与操作系统更紧密集成的功能,比如原生对话框、控件和多线程支持。标题提到的是SWT的4.3...

    swt

    `SWT线程.pdf`文件可能是详细讲解SWT中线程管理的教程,可以帮助读者深入理解如何在SWT应用中正确处理多线程。 总的来说,SWT是一个强大且灵活的GUI库,对于希望开发高性能、原生感的Java桌面应用的开发者来说,是...

    SWT视频播放器

    6. **多线程处理**:为了保证界面的响应性,视频播放通常在后台线程进行,防止阻塞主线程。 7. **音频同步**:视频播放器还需要处理音频和视频的同步问题,确保音画同步。 8. **格式支持**:集成的多媒体库决定了...

    SWT创建Shell窗口

    SWT(Standard Widget Toolkit)是Java编程环境中用于创建图形用户界面(GUI)的一种库,它提供了与操作系统原生UI组件紧密集成的能力。本篇将详细讲解如何使用SWT来创建一个基本的Shell窗口。 首先,我们需要理解...

    java swt 跳棋程序 源码

    Java SWT(Standard Widget Toolkit)是Java编程环境中用于创建桌面应用程序的一种图形用户界面(GUI)工具包,它是Eclipse项目的组成部分。SWT 提供了与操作系统底层更直接的交互,使得开发者可以创建性能优异且与...

Global site tag (gtag.js) - Google Analytics