search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

尚學堂java學習筆記:針對用戶界面的多線程

現在,我們也許能用一個線程解決在Counter1.java 中出現的問題。採用的一個技巧便是在一個線程的run方法中放置子任務」——亦即位於go內的循環。一旦用戶按下Start 按鈕,線程就會啟動,但馬上結束線程的創建。這樣一來,儘管線程仍在運行,但程序的主要工作卻能得以繼續(等候並響應用戶界面的事件)。 現在,Counter2 變成了一個相當直接的程序,它的唯一任務就是設置並管理用戶界面。但假若用戶現在按下Start 按鈕,卻不會真正調用一個方法。此時不是創建類的一個線程,而是創建SeparateSubTask,然後繼續Counter2 事件循環。注意此時會保存SeparateSubTask 的句柄,以便我們按下onOff 按鈕的時候,能正常地切換位於SeparateSubTask 內部的runFlag(運行標誌)。隨後那個線程便可啟動(當它看到標誌的時候),然後將自己中止(亦可將SeparateSubTask 設為一個內部類來達到這一目的)。

SeparateSubTask 類是對Thread 的一個簡單擴展,它帶有一個構建器(其中保存了Counter2 句柄,然後通過調用start來運行線程)以及一個run——本質上包含了Counter1.java go內的代碼。由於SeparateSubTask 知道自己容納了指向一個Counter2 的句柄,所以能夠在需要的時候介入,並訪問Counter2TestField(文本欄位)。

按下onOff 按鈕,幾乎立即能得到正確的響應。當然,這個響應其實並不是「立即」發生的,它畢竟和那種由「中斷」驅動的系統不同。只有線程擁有CPU 的執行時間,並注意到標記已發生改變,計數器才會停止。

1. 用內部類改善代碼

下面說說題外話,請大家注意一下SeparateSubTask Counter2 類之間發生的結合行為。SeparateSubTaskCounter2 「親密」地結合到了一起——它必須持有指向己「父」Counter2 對象的一個句柄,以便自己能回調和操縱它。但兩個類並不是真的合併一個類(儘管在下一節中,我們會講到Java 確實提供了合併它們的方法),因為它們各自做的是不同的事情,而且是在不同的時間創建的。但不管怎樣,它們依然緊密地結合到一起(更準確地說,應該叫「聯合」),所以使程序代碼多少顯得有些笨拙。在這種情況下,一個內部類可以顯著改善代碼的「可讀性」和執行效率.

這個SeparateSubTask 名字不會與前例中的SeparateSubTask 衝突——即使它們都在相同的目錄里——因為它已作為一個內部類隱藏起來。大家亦可看到內部類被設為private(私有)屬性,這意味著它的欄位和方法都可獲得默認的訪問許可權(run除外,它必須設為public,因為它在基礎類中是公開的)。除Counter2i之外,其他任何方面都不可訪問private 內部類。而且由於兩個類緊密結合在一起,所以很容易放寬它們之間的訪問限制。在SeparateSubTask 中,我們可看到invertFlag方法已被刪去,因為Counter2i 現在可以直接訪問runFlag。此外,注意SeparateSubTask 的構建器已得到了簡化——它現在唯一的用外就是啟動線程。Counter2i 對象的句柄仍象以前那樣得以捕獲,但不再是通過人工傳遞和引用外部對象來達到這一目的,此時的內部類機制可以自動照料它。在run中,可看到對t 的訪問是直接進行的,似乎它是SeparateSubTask 的一個欄位。

父類中的t 欄位現在可以變成private,因為SeparateSubTask 能在未獲任何特殊許可的前提下自由地訪問它——而且無論如何都該儘可能地把欄位變成「私有」屬性,以防來自類外的某種力量不慎地改變它們。

無論在什麼時候,只要注意到類相互之間結合得比較緊密,就可考慮利用內部類來改善代碼的編寫與維護。



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦