組合對象
我們不希望爲了獲得線程安全而去每次分析內存訪問;而希望線程安全的組件能夠以安全的方式組合成更大的組件或程序。
4.1 設計線程安全的類
4.1.1 收集同步需求
4.1.2 狀態依賴的操作
4.1.3 狀態所有權
4.2 實例限制
即使一個對象不是線程安全的,你也可以讓他安全地用於多線程。
比如確保它只被單一的線程訪問,也可確保所有的訪問都正確地被鎖保護。
實例限制是構建線程安全類的最簡單方法之一。
4.2.1 Java監視器模式
對象封裝所有的可變狀態,並由自己的內部鎖保護。
4.2.2 範例:機動車追蹤器
先複製數據,再返回給用戶,這種實現方式部分地維護這線程安全。
4.3 委託線程安全
把線程的安全性委託給線程安全的類,就是委託線程安全。
4.3.2 非狀態依賴變量
4.3.3 當委託無法勝任時
狀態變量lower和upper不是彼此獨立的,不能將安全性委託個線程安全的狀態變量上。
4.3.4 發佈底層的狀態變量
4.4 向已有的線程安全類添加功能
直接向類中加入新方法,意味着所有實現類同步策略仍然包含在一個源代碼文件中,便於理解和維護。但是通常不可能,無法操作原始類。
另一個方法是擴展類,可能會改變父類的同步策略。
4.4.1 客戶端加鎖
list操作聲明瞭synchronized,但是使用了不同的鎖,將意味着putIfAbsent對list的其他操作而言,並不是原子化。
正確的方法是使用相同的鎖:
4.4.2 組合
向已有的類中添加一個原子操作,還有更健壯的選擇:組合。
通過使用內部鎖,引入了一個新的鎖層。