J2SE 5.0平台包含了一個新的並發工具程式包。這個程式包中的類替並發類(concurrent classe)或並發設計中使用的應用程式建立阻塞(blocking)。該並發工具包含下面一些內容:
高效能的、靈活的線程池
非同步執行事務的架構組件
為並發訪問最佳化過的集合類宿主(host)
本文介紹了J2SE 5.0架構組件類和它們的重要特性。本文的下載代碼提供了一些簡單的、容易使用的樣本,它示範了所有的新線程架構組件類。你在閱讀文章內容之後運行這些樣本可以使自己對這些特性有更好的理解。
Executor(執行器)架構組件
Executor架構組件提供了一個簡單的、標準的、可擴充的類,它提供了一些有用的功能,如果沒有這些功能,我們要手工實現這些它們,會覺得十分單調和困難。該架構組件使調用、調度和執行的操作標準化了。它通過一組執行策略為控制非同步事務提供了支援。
Executor介面執行已提交的可以啟動並執行事務。它提供了一條途徑,允許我們把事務提交從事務執行機制中分離出來。程式員通常使用Executor代替顯式地(explicitly)建立線程。Executor介面也提供事務的同步和非同步執行。
對於同步執行,使用下面的命令:
Class MySynExecutor implements Executor{
public void execute(Runnable r) {
r.run();
}
}
對於非同步執行,使用下面的命令:
Class MyASynExecutor implements Executor{
public void execute(Runnable r) {
new Thread(r).start();
}
}
ExecutorService(執行器服務)類
ExecutorService類為管理一個或多個非同步事務的終止和跟蹤事務執行的過程提供了方法。代碼下載中的MyExecutorService.java檔案示範了管理事務終止的過程。它初始化了大小為三個的線程池,然後依次添加了線程。當線程的數量達到線程池的大小限制時,它調用關閉(shutdown)方法。在調用shutdown()方法之後,這個線程池不再接受新事務的執行。在等待十秒以後,該線程池調用shutDownNow()。這個方法會盡最大的努力來終止所有運行中的事務。在樣本中,應用程式試圖終止運行中的線程失敗了。
ScheduledExecutorService(調度執行器服務)
ScheduledExecutorService類是我的最喜歡的類。它對於調度那些周期性執行的事務非常方便,而周期性執行的事務對於清除工作(例如清除你的應用程式建立的臨時檔案等等)尤其有用。下載代碼中的MyScheduledExecutorService.java檔案通過每五秒鐘發出"嘟嘟"一聲示範了調度的過程:
final Runnable beeper = new Runnable() {
public void run() { System.out.println("beep"); }
};
final ScheduledFuture beeperHandle =scheduler.scheduleAtFixedRate(beeper, 1, 5, SECONDS);
Future和FutureTask
在Java的早期版本中,查詢運行中的線程狀態,以及使線程在執行之後返回一個值是非常困難的。由於run(運行)方法返回void,你必須編寫大量的代碼從線程中返回一個值。使用過這種方法的程式員肯定瞭解其痛苦的經曆。
你可以使用Future介面或者FutureTask類從非同步執行的線程中得到一個傳回值。Future介面提供了檢查計算過程是否完成、檢索計算結果或終止計算過程的一些方法。FutureTask類提供了Future介面方法的基本實現(implementation)。只有計算過程完成以後才能檢索結果;如果計算過程沒有完成,get方法會被阻塞(block)。
下載代碼中的MyStringReverser.java檔案示範了FutureTask類的使用,並提供了一個容易理解的樣本。它以每秒鐘一個字元的速度從後向前顯示提交的字串,同時主線程檢測事務是否完成了:
while(!future.isDone()){
System.out.println("Task not yet completed.");
try{
Thread.currentThread().sleep(500);
}catch(InterruptedException ie){
System.out.println("Will check after 1/2 sec.");
}
}
在事務完成以後,就使用get方法從Future對象中檢索結果:
System.out.println("Here is result..."+future.get());
ThreadPoolExecutor(線程池執行器)