java Swing GUI程序啟動時,JVM會啟動多個線程,Swing并不是線程安全的,如果處理不當Swing程序會反應遲鈍,JavaSE6開始引用SwingWorker能夠改善Swing程序結構,提高界面的靈活性。
事件派發線程
當界面程序啟動時,會調用界面的主方法
Java.awt.EventQueue.invokeLater(new Runnable(){ public void run(){ new NumberAddutionUI().setVisible(true); } } invoketLater方法的意思是提交程序在事件派發線程(EDT)上執行其Runnable任務,此點是創建UI的點,也就是線程開始將控制權轉交給UI的點。之后,主線程結束,程序在EDT中運行。由于EDT線程負責GUI組件的繪制和更新,所有事件處理都在EDT上進行,程序同UI組件和其基本數據的交互只允許在EDT上進行。由此可知EDT隊列非常繁忙,幾乎每一次GUI交互和事件都是通過它完成的。所以事件隊列中的任務必須非常快,否則就會阻塞其他任務。因此,所有耗時的任務都不應該放在EDT上進行,同時Swing編程也要注意以下幾點, 1)從非EDT線程訪問UI主鍵及其事件監聽器會廢紙界面更新和繪制錯誤。
2)從EDT上執行耗時任務線程會使程序失去響應,這會使GUI事件阻塞在隊列中得不到處理。
3) 應使用獨立的任務線程來執行耗時計算或輸入輸出密集型任務,想數據庫通信,訪問網站資源,讀寫大量數據的文件。
總之任何干好活延遲UI事件處理只應該在獨立任務線程中;在主線程或任務線程中同Swing組件或其默認數據模式進行的交互都是非線程安全的。
SwingWorker類
SwingWorker類的定義
Swing Worker類能夠幫助線程與Swing EDT之間的交互,有助于分離Swing EDT和任務線程。SwingWorker的使用能夠使他們各負其責,對于EDT來說,就是繪制和更新界面,并響應用戶輸入;對于線程任務來說,就是執行和界面無直接關系的耗時任務和I/O密集型操作。
SwingWorker類的定義 當界面程序啟動時,會調用界面的主方法
public abstract calss SwingWorker<T,V>extends Object implements RunnableFutureSwingWorker是抽象類,因此必須繼承它才能執行所需的特定任務。該類對象產生類型為T的結果值以及類型為V的進度數據。
RunnableFuture是Runnable和Future兩個接口的簡單封裝。
SwingWorker實現了兩個父類接口大部分方法。
| 方法 | 功能 |
|---|---|
| boolean cancel(boolean mayInterruptIfRunning) | 取消正在進行的工作。 |
| T get() | 獲取類型為T的結果值。該方法將一直處于阻塞狀態,直到結果可用。 |
| T get(long timeout,TimeUnit unit) | 獲取類型為T的結果值,將會一直阻塞直到結果可用或超時。 |
| boolean isCancelled() | 判斷任務線程是否被取消。 |
| boolean isDone() | 判斷任務線程是否完成。 |
| abstract T doInBackground() | 該方法作為線程的一部分執行,負責完成線程的基本任務,并以返回值(類型為T)作為線程的執行結果。繼承類必須覆蓋該方法并確保包含或代理任務線程的基本任務。不要直接調用該方法,應使任務對象的execute方法來調度執行。 |
| PRotected void done() | 在doInBackground()方法完成之后,SwingWorker在EDT上激活done方法。如果任務需要在完成后使用線程結果更新GUI組件或者做些清理工作,可覆蓋該方法來完成. |
| void publish(V…data) | 傳遞中間進度數據到EDT。從doInBankground方法調用該方法。 |
| void process(Listdata) | 覆蓋該方法處理任務線程的中間結果數據 |
| void execute() | 為SwingWorker線程的執行預訂這個SwingWorker對象。 |
任務線程有幾種狀態:使用SwingWorker.StateValue枚舉值來表示:PENDING、STARTED和DONE線程一旦創建就處于PENDING 狀態,當doInBackground方法開始時,任務就進入STARTED狀態,當doInBackground方法完成后,任務線程就出入DONE狀態 任務對象有一個進度屬性,隨著任務進展時,可以將這個屬性從0更新到100標識任務進度,當該屬性發生變化時,任務通知處理器進行處理。
SwingWorker的工作模式
當Swing GUI 程序執行耗時任務時,在EDT中創建一個SwingWorker對象。在該對象編寫有實現耗時任務代碼的doInBackground方法中執行耗時操作,該方法在EDT中被使用execute方法調用,在SwingWorker線程中執行。在doInBackground方法中不時地調用public來發布中間數據。publish方法使得process方法在EDT中執行來處理進度數據。當工作完成時,在EDT中調用done方法以便完成UI的更新,在done方法中可以用get方法獲取doInBackground的執行結果

新聞熱點
疑難解答