本文參考了 http://space./13685345/viewspace-374940,原文作者:javagui
EventQueue的派發(fā)機制由單獨的一個線程管理,這個線程稱為事件派發(fā)線程(EDT)”。和其他很多桌面API一樣,Swing將GUI請求放入一個事件隊列中執(zhí)行。
這就需要使用其它線程來處理這些耗時地任務(wù),比如使用一個新的線程來處理這些耗時任務(wù)。這樣可以處理處理事件的程序快速地返回,而不至于影響其它事件的執(zhí)行。但是在處理過程中,我們必須保證處理的代碼不能影響到界面的變化。主要依賴于以下的原則: EDT要處理所有GUI操作,它是職責(zé)分明且非常忙碌的。也就是說你要記住兩條原則:一、職責(zé)分明,任何GUI請求都應(yīng)該在EDT中調(diào)用。二、需要處理的GUI請求非常多,包括窗口移動、組件自動重繪、刷新,它很忙,所以任何與GUI無關(guān)的處理不要由EDT來負(fù)責(zé),尤其是I/O這種耗時的操作。
那么,如果我們要在我們新建的線程中,要調(diào)用界面處理程序應(yīng)該如何去做呢。這時可以使用SwingUtilities工具類的invokeLater或者invokeAndWait方法來執(zhí)行界面更新程序。這兩個方法,是將我們傳遞的一個線程方法放入到事件分發(fā)線程當(dāng)中,這樣可保證所有更新界面的程序都能夠在事件處理線程中運行。 說到底,什么是事件處理線程呢,什么才算在事件處理線程當(dāng)中呢。很簡單的理解,我們添加到各個對象上的listener實現(xiàn)中的處理代碼,都是在事件處理線程中運行的。比如按鈕的點擊事件處理程序,actionPerformed方法,這都是在事件處理線程中調(diào)用的。 通過上述對事件隊列和EDT的分析,有這樣一種體會:事件隊列是一個非常好的處理并發(fā)設(shè)計模型,不僅 Swing用它來處理后臺,Java的很多地方都在用,只不過對于處理服務(wù)器端的并發(fā)請求有多個處理線程在等候處理請求,也就是常說的線程池。而對于單用戶的桌面應(yīng)用,單線程調(diào)用要比多現(xiàn)成API更簡單,“Swing后臺這樣做是為了保證事件的順序和可預(yù)見性”,而且相對于服務(wù)器,客戶端桌面層的請求要少得多,所以單線程就足夠應(yīng)對了。 那么,swing的分發(fā)線程機制和多線程之間有什么聯(lián)系呢?swing中的線程處理原則在于,界面處理程序在事件處理線程中運行,而其它邏輯運算在其它線程中運行,通過invokeLator和invokeAndWait和事件處理線程交互。而我們通過使用的多線程,在一定程度上也是這樣處理。主要的程序處理在主線程中運行,當(dāng)接收到處理請求時,則分發(fā)線程進(jìn)行,即要保證主線程不會因為事件處理而被阻塞,同時也要保證事件都能夠被處理。比如經(jīng)常使用的web開發(fā)中的socket請求。
轉(zhuǎn)載請標(biāo)明出處:i flym |
|