swt中的多线程机制

文章出处:DIY部落( http://www.diybl.com/course/3_program/java/javajs/20071211/91567.html)
 
今天比较郁闷在写一个swt的线程程序时搞了4个多小时,晕啊!
      SWT中的多线程机制和awt/swing中些不同,这个大家应该都知道,不过还是要说下,
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()。
  上面几点都是书里面的原话,不做阐述了.下面我要说的是一个写法的问题,不能小瞧啊,后果很严重.
如果一个线程他要做的事需要很久比如5分钟,像我这样的初学swt的人一定是new了一个线程然后
getDisplay().asyncExec(线程对象); 结果虽然执行成功,但是界面确处于挂起状态(假死),直到执行结束,不过要说的是的确是异步执行的,还是ui却不知道为什么停止用户响应,原理暂时先不去理了,swt源码太复杂了.
这里面就要引出一个问题为什么不 像下面这么写呢?
 Thread thread = new Thread(线程对象);
   thread.start();
因为swt中非UI线程中调用窗口控件如果不像上面种写法那样写的话,会抛
org.eclipse.swt.SWTException: Invalid thread access这个异常
在swt中程序启动时只一个主线程,在这里与awt和swing是不一样的,它不允许其他线程访问UI主线程中的部件,具读过swt源码的人说AsyncExec方法根本就没有新启动一个线程而是由Synchronizer调用其中的 run 方法而已.如果是这样的话,也就难怪UI会挂起.
解决这个问题的一个比较好的方法是如果要异步执行的线程所做的工作非常少的话,就无所谓了,如果异步线程需要执行很长时间的话,应该像下面这样启动线程
 Thread thread = new Thread(线程对象);
   thread.start();
在线程对象里面所调用到UI部件的地方
  classFinder.getGui().getDisplay().syncExec(new Runnable() {
   public void run() {
       //do run
   }
  });
历经几个小时问题终于解决了这里做个总结吧.
我对swt多线程的评价
 swt的syncExec ,asyncExec 以及timerExec都是伪线程执行方法,把它看成特别的Synchronizer调用就可以了,
syncExec ,asyncExec 以及timerExec执行的线程要做的事只是改变UI部件的属性而已执行时间不能太长.此外的其他操作仍然由传统的线程来做
发布了19 篇原创文章 · 获赞 3 · 访问量 9744

猜你喜欢

转载自blog.csdn.net/pinghuqiuyue9/article/details/50966438