第四章:對象的組合——java並發編程實戰


一、設計線程安全的類

  • 找出構造對象狀態的所有變量(若變量為引用類型,還包括引用對象中的域)
  • 約束狀態變量的不變性條件
  • 建立對象狀態的並發訪問管理策略(規定了如何維護線程安全性)

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實例來操作,並通過自身的內置鎖增加一層額外的加鎖,同時添加了新的同步方法。

 

五、將同步策略文檔化


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM