SWT中处理多线程<o:p></o:p>
转自:http://blog.csdn.net/baobeiSimple/archive/2007/08/22/1753910.aspx
在Eclipse中,SWT是最重要的基石之一,负责了跨平台的本地界面显示,使Java也能够编写与系统相同的界面元素。在SWT中处理多线程也是其重要技术的表现。<o:p></o:p>
SWT有两个使用方法,分别是asyncExec和syncExec,前者是 异步执行与界面有关的操作,后者反之。为什么要这么做?由于SWT单独有一个线程(主线程)处理界面显示,数据显示等,如果要在其他线程中操作界面元素, 就必须使用上述两个方法执行,即将另外线程的操作交给主线程处理。<o:p></o:p>
而SWT的多线程远没有这么简单。一般情况下,在SWT中运行线程时,其主线程不能阻塞,也能响应用户请求,比如鼠标和菜单等。在这种情况下,需要新建Thread来处理逻辑,在这个Thread中,必须使用上面的两个方法处理界面数据。<o:p></o:p>
以下是一个简单的例子,启动10个线程,在5秒的时间内,刷新列表中各行的字符串,在这个过程中,主界面依然能够响应鼠标请求。代码有点“圆环套圆环”的感觉。<o:p></o:p>
<v:shapetype o:spt="75" coordsize="21600,21600" filled="f" stroked="f" id="_x0000_t75" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:extrusionok="f" o:connecttype="rect" gradientshapeok="t"></v:path><o:lock v:ext="edit" aspectratio="t"></o:lock></v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" alt="" style="WIDTH: 299.25pt; HEIGHT: 224.25pt"><v:imagedata o:href="http://tenyears.cn/dl/swtthread.jpg" src="file:///C:\DOCUME~1\gujin\LOCALS~1\Temp\msohtml1\01\clip_image001.jpg"></v:imagedata></v:shape><!--[if !vml]--><!--[endif]--><o:p></o:p>
import org.eclipse.swt.SWT; |
说明:<o:p></o:p>
下面分析startThread()
这个方法可以用于当这个方法的执行需要很长时间,而在其执行期间又不会影响其他方法的执行。本方法中的最后一句:
BusyIndicator.showWhile(shell.getDisplay(), refresh);<o:p></o:p>
是关键,如果没有这一句则,执行此方法时,其他方法不能运行。<o:p></o:p>
这个方法的必须包含两个Runnable的是实现:其中外层用于<o:p></o:p>
BusyIndicator.showWhile()方法中作为参数<o:p></o:p>
长时间的运行代码应该放在里面的一个runnable实现的run()方法中,例如:<o:p></o:p>
<o:p> </o:p>
final Runnable runOne = new Runnable() {<o:p></o:p>
public void run() {<o:p></o:p>
final long start = System.currentTimeMillis();<o:p></o:p>
while ((System.currentTimeMillis() - start) < 1000*10) {<o:p></o:p>
cnt++;<o:p></o:p>
} <o:p></o:p>
};<o:p></o:p>
}; <o:p></o:p>
<o:p> </o:p>
startThread方法可以简化为:(这个方法更清晰)<o:p></o:p>
<o:p></o:p>
public void startThread() {<o:p></o:p>
<o:p></o:p>
final Runnable refresh = new Runnable() {<o:p></o:p>
public void run() { <o:p></o:p>
<o:p></o:p>
final Runnable runOne = new Runnable() {<o:p></o:p>
public void run() {<o:p></o:p>
final long start = System.currentTimeMillis();<o:p></o:p>
while ((System.currentTimeMillis() - start) < 1000*10) {<o:p></o:p>
cnt++;<o:p></o:p>
} <o:p></o:p>
};<o:p></o:p>
}; <o:p></o:p>
Thread thread = new Thread(runOne);<o:p></o:p>
thread.start();<o:p></o:p>
}<o:p></o:p>
};<o:p></o:p>
BusyIndicator.showWhile(shell.getDisplay(), refresh);<o:p></o:p>
}<o:p></o:p>