SwingWorker()構造器的線程
演示程序用SwingWorker()構造器在后臺執行費時的操作,然后更新UI。
這個演示程序所用的SwingWorker是基于《使用SwingWorker線程》文中提出的SwingWorker類,但重新實現了它以修正一處競態條件,添加超時支持,和改進了異常處理。
這個新的實現還基于DougLea的util.concurrent包的FutureResult類(參見“參考資料”一節)。由于大量依賴了FutureResult所做的工作,SwingWorker類的實現是簡單而靈活的。
本節的余下部分更詳細地描述了實現的細節,請繼續往下看或直接跳到后面下載源碼。
RunnableFutureResult
FutureResult,正如它的名字所暗示的,它是用來保持某動作的結果的。它被設計成和一個Callable共同使用,Callable是一個會返回結果的runnable動作:
- publicinterfaceCallable{
- Objectcall()throwsException;
- }
新的SwingWorker是一個RunnableFutureResult。在運行時,它把結果設成construct()的返回值,然后在事件派發線程中調用finished()方法。(注意:SwingWorker是一個抽象類;你要子類化它并實現construct()和finished()。)
下面的代碼來自SwingWorker的run()方法:
- Callablefunction=newCallable(){
- publicObjectcall()throwsException{
- returnconstruct();
- }
- };
- RunnabledoFinished=newRunnable(){
- publicvoidrun(){
- finished();
- }
- };
- setter(function).run();
- SwingUtilities.invokeLater(doFinished);
***段把construct()轉換成一個Callable動作,第二段把finished()轉換成作為Runnable的doFinished。然后setter(function)被運行,doFinished被調用。
setter(function)
上面缺少的部分是setter(function)。它創建一個刻板的Runnable。在運行時,這個Runnable調用參數指定的function,然后給結果設置返回值。下面是來自FutureResult的代碼:
- publicRunnablesetter(finalCallablefunction){
- returnnewRunnable(){
- publicvoidrun(){
- try{
- set(function.call());
- }
- catch(Throwableex){
- setException(ex);
- }
- }
- };
- }
注意try-catch塊所作的防護。如果construct()拋出任何東西(Exception、Error等等),都會被捕捉并記錄下來。
不要搶跑:先construct,再start
調用start()來啟動worker線程。這是修訂版的SwingWorker和原來版本的一個重要區別。
在原來的版本中,SwingWorker()構造器自動啟動線程,這種做法帶來了一個線程和子類構造器競爭的危險:當SwingWorker()構造器已啟動了線程,而子類的構造器還沒完成。彌補方法是,先構造SwingWorker,然后再調用start()。
順便一提,RemoteTable并不調用start()。正確來說,SwingWorker是作為一個Runnable被QueuedExecutor執行的。
【編輯推薦】




















