一、設計線程安全的類
在設計線程安全類的過程中需要考慮一下要素;
2.構建線程安全的類之實例封閉
實例封閉是指將類的狀態變量(基本類型或者引用類型)封裝在類的內部,只是對外暴露相應的接口,并且在接口上實現同步,如果要訪問該類的狀態變量只能通過開放的同步接口,這樣調用客戶端不需要進行多余的同步代碼。

對于引用類型的狀態變量,在通過公開的接口訪問該狀態時候,一定要注意不要把這個引用對象(如果對象是可變對象,需要復制,如果是不可變對象則不需要)逸出,通常可以通過clone()方法返回該引用的一個副本。
(1)實例封閉之java監視器模式
當從頭構建一個線程安全的類,或者將多個非線程安全的類組合成一個線程安全的類時,java監視器模式是非常有用的,但是如果類中的各個組件已經是線程安全的,就需
要考慮線程安全性的委托了。
對象只有在完全初始化后,其final變量對其它線程才是可見的。這說明,final變量的初始化可以在不使用synchronization的情況下實現線程安全。這樣,final變量實現了
真正意義上的final(即,不-可-變),而不會在初始化過程中、后在多線程中看起來會改變。
3. 線程安全性的委托 (1)如果一個對象中只有一個線程安全的狀態變量,則可以完全可以見對該狀態變量的訪問委托給變量本身;如果對象中有n個互相獨立的線程安全的狀態變量時,也可以簡單
將對變量的安全訪問委托給狀態變量即可。但是如果這些狀態變量之間有制約關系,則可能還需要額外的同步手段。
4. 構建線程安全的類之發布底層的狀態變量
當把一個類線程的安全性委托給底層的狀態變量時,什么情況下才能發布這個狀態變量使客戶端代碼可以修改該底層狀態變量的值?

5. 構建線程安全類之在現有的線程安全類中添加功能 (1)客戶端加鎖機制 客戶端加鎖是指對于使用某個對象X的客戶端代碼,必須使用X本身用于保護其自身狀態的鎖來保護這段客戶端代碼,才能實現真正意義上的同步和原子性。要使用客戶端加鎖,客戶端必須知道對象X使用的是哪一個鎖。錯誤的客戶端加鎖代碼:

注意:此處客戶端的同步是完全沒有作用的,因為list中同步使用的鎖肯定不是此處ListHelper中使用的鎖。

(2)當為現有的類添加一個原子操作時,有一種更好的方法:組合


新聞熱點
疑難解答