Java多線程之"事件分發線程"----Event Dispatch Thread

當運行GUI小程序(Applet)或應用程序(Application)時,main()方法中的代碼會建立一個GUI並設置事件句柄.當調用Frame,Dialog,Window的setVisible(true)或瀏覽器顯示Applet時,我們就是在和GUI交互. 

問題是你的main()可能不會只停留在用戶界面上,它可能會作一些其他方法.比如計算PI直到小數點後40000位.如果用戶在和GUI交互之前要等待一段漫長的時間的話,他們可能就會退出。

  所以AWT庫實現了監控GUI交互的線程.這個線程實際上就是循環檢查系統事件隊列(System Event Queue)是否有鼠標點擊,鍵盤按下或其他系統事件(也可以把自己的事件加入系統事件隊列,這就是將在下一片中提到的).這個線程就是事件分發線程(Event Dispatch Thread),它是java.awt.EventDispatchThread的一個實例.事件分發線程是Swing和AWT中最重要的,在繪製,更新和顯示組件和受控的應用程序方面扮演這關鍵的角色.和這個線程緊密相關的是一個FIFO事件的隊列----系統事件隊列,它是java.awt.EventQueue的一個實例.每個事件都是按順序一個一個的執行的,這是爲了避免在組件重繪的過程中組件的狀態發生變化.我們一定要小心不要再事件分發線程之外分發一個事件.例如,在另外執行的線程中直接調用fireXX()方法是不安全的.另外,應當儘量使事件句柄和繪製方法儘可能的短小精悍,否則系統的反應會變得不靈敏,有些時候甚至看起來象是死機了. 

  事件分發線程(Event Dispatch Thread)從系統事件隊列取出並檢測對其採取何種處理.如果是對一個組件的點擊,就爲這個組件調用處理句柄.接下來,那個組件再發送其他事件.例如,假設你單擊了一個JButton,事件分發線程傳遞一個鼠標單擊到JButton, JButton把它解釋成一個"按鈕按下",並調用它的actionPerformed方法.所有註冊過的監聽器的actionPerformed方法都會得到調用. 

  javax.swing.EventLisenerList是一個包含XXEvent/XXListener對的數組.所有的組件(JComponent)和模型(model)都有自己的EventListenerList數組.當Listener被加入或刪除的時候,新的EventListenerList數組會通過System.arrayCopy()被創建.之所以不使用Vector而代之以數組是因爲考慮到執行效率的原因. 

  AWT線程(事件分發線程)也負責GUI的重繪.任何時候調用了repaint方法,一個刷新請求就被放入事件隊列.只要AWT線程看到刷新請求,它就會檢查GUI的破壞區和被標記爲invalid的組件,然後調用適當的方法輸出GUI和需要重繪的組件.  

  所有的AWT組件都是線程安全的,在線程安全的方式下,當你調用一個Label的setText()方法時,顯示是同步的,你不會看到一半是老的內容一半是新的內容的情況.而swing組件不是線程安全的.你必須確保任何對組件的更改都通過事件分發線程處理.如果一個線程即更新又顯示一個組件,你必須保證他們的一致性.:-) 

Please wait for the next article :   

Java多線程之建立自己的線程安全方法----Build Our Own Thread-safe Methods 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章