標籤:ons 程式 一個 tab 條件 vector return 同步機制 com
一、設計安全執行緒的類
- 找出構造對象狀態的所有變數(若變數為參考型別,還包括引用對象中的域)
- 約束狀態變數的不變性條件
- 建立對象狀態的並發訪問管理原則(規定了如何維護執行緒安全性)
1、收集同步需求(找出複合操作、多個變數遵循原子性的操作等)
2、依賴狀態的操作(找出操作是否基於先驗條件,例:取出當隊列不為空白)
3、狀態的所有權(對象被哪些線程所有,哪些線程可以操作對象)
二、執行個體封閉
將資料封裝在對象內部,可以將資料的訪問限制在對象的方法上,確保簡單正確的持有鎖。(因為無需觀察整個程式,只需檢查當前類)
Java提供封裝器對ArrayList、HashMap等容器物件提供安全執行緒保護
1、Java監視器模式:把對象的所有可變狀態封裝起來,並使用對象的內建鎖保護
使用私人鎖而不是內建鎖的優點:(private final Object myLock = new Object();)
- 私人鎖可以將鎖封裝起來,客戶代碼無法得到鎖
- 客戶可以通過公有方法來訪問鎖,以便參與到同步策略中去。
2、執行個體:基於監視器模式的車輛追蹤
MutablePoint不一定是安全執行緒的,但該類一定是安全執行緒的,因為它包含的Map對象與Map中的Point對象都未曾發布,並且滿足執行個體封閉。
三、執行緒安全性的委託
通過多個安全執行緒的類組成的類不一定是安全執行緒的
委託:通過委託類的執行緒安全性判斷被委託類的執行緒安全性
1、委託給單個安全執行緒狀態變數可以保證執行緒安全性
2、委託給多個相互獨立的安全執行緒狀態變數可以保證執行緒安全性
3、如果類包含多個安全執行緒狀態變數的符合操作,則無法保證執行緒安全性,可以通過加鎖機制保證
4、發布:如果一個狀態變數是安全執行緒的,並且沒有不變性條件約束它(例:大於0),在變數操作上沒有不允許的狀態轉換,則可以安全發布
5、安全發布底層狀態的安全執行緒類
1 @ThreadSafe 2 public class PublishingVehicleTracker { 3 private final Map<String, SafePoint> locations; 4 private final Map<String, SafePoint> unmodifiableMap; 5 6 public PublishingVehicleTracker(Map<String, SafePoint> locations) { 7 this.locations = new ConcurrentHashMap<String, SafePoint>(locations); 8 this.unmodifiableMap = Collections.unmodifiableMap(this.locations); 9 }10 11 public Map<String, SafePoint> getLocations() {12 return unmodifiableMap;13 }14 15 public SafePoint getLocation(String id) {16 return locations.get(id);17 }18 19 public void setLocation(String id, int x, int y) {20 if (!locations.containsKey(id))21 throw new IllegalArgumentException("invalid vehicle name: " + id);22 locations.get(id).set(x, y);23 }24 }
四、現有的安全執行緒類中添加功能
例:在Vector中添加”若沒有則添加“功能,可以使用拓展的辦法,BetterVector繼承至Vector並對該符合操作通過同步機制增加原子性
1、用戶端加鎖機制
使用某個對象的代碼時必須使用該對象本身用於保護其狀態的鎖,不推薦(同步的實現被分到兩個不相關的類中)
當沒有使用同一個鎖,不足以提供安全執行緒保護:
2、組合
ImprovedList將List的操作委託給底層的list執行個體來操作,並通過自身的內建鎖增加一層額外的加鎖,同時添加了新的同步方法。
五、將同步策略文檔化
java並發編程實戰:第四章----對象的組合