設計線程安全的類要包括三個基本要素: .)找出構成對象狀態的全部變量; .)找出約束狀態變量的不變性條件; .)創建對象狀態併發訪問管理策略。安全
一、實例封閉(使用內置鎖保護訪問方法)併發
public class PersonSet { @GuardedBy("this") final Set<Person> mySet = new HashSet<Person>(); public synchronized void addPerson(Person p){ mySet.add(p); Collections.synchronizedList(new ArrayList<String>()); //SynchronizedList裝飾器模式 } public synchronized Set<Person> getSet(){ return mySet; } static class Person { } }
二、監視器模式(使用私有的鎖而不是內置鎖)this
public class PrivateLock { private final Object myLock = new Object(); @GuardedBy("myLock") Widget widget; void someMethod(){ synchronized(myLock){ //TODO } } }
私有鎖的優勢(不用內置鎖不用其餘能夠經過公有方式訪問的鎖): .)私有鎖對象可能將鎖封裝起來,客戶端沒法獲得鎖,只能經過公有方法訪問鎖; .)公共訪問的鎖是否被正確使用須要檢查整個程序。線程
3.線程安全性的委託 .)單個狀態變量的集合委託給線程安全的集合; .)相互獨立的多個狀態變量,即多個狀態變量之間不會引入不變性條件; .)發佈線程安全的狀態。設計
四、現有的線程安全類中添加功能 .)擴展方法比直接添加代碼到類中更加脆弱,會改變同步策略; .)客戶端加鎖機制:使用某個對象X的客戶端代碼,使用X自己用於保護狀態的鎖來保護這段代碼,必須知道對象X使用的是哪個鎖,缺點是派生類的行爲與基類的實現耦合在一塊兒,破壞同步策略的封裝性; .)組合(Composition)是最合適的,裝飾器模式。code