Java 中ConcurrentHashMap的一些知識點
1.ConcurrentHashMap
ConcurrentHashMap在JDK1.8以後不採用分段鎖的機制,取消了segments欄位,直接採用transient,volatile,HashEntry<K,V>table儲存資料,採用table陣列元素作為鎖,從而實現了對每一行資料進行加鎖,進一步減小併發衝突的概率;將原先table陣列+單向連結串列的資料結構,變更為table陣列+單向連結串列+紅黑樹的結構(捂臉,不會啊,後面進一步學習)。
在JDK1.6中ConcurrentHashMap使用鎖分段技術提高併發訪問率,首先將資料分成一段一段的儲存,然後給每一段資料配一個鎖,當一個執行緒佔用鎖訪問其中的一個數據時,其他段的資料也能被其他的執行緒訪問。在JDK1.8以後已經拋棄了Segment分段鎖機制,利用CAS+Sychronized來保證併發更新的安全,底層依然採用陣列+連結串列+紅黑樹的儲存結構。
在這兒再說一下CAS
CAS(Compare and Swap),即比較並替換,實現併發演算法時常用的一種技術。CAS的思想很簡單:三個引數,一個當前記憶體指V,舊的預期值A,即將更新的值B,當且僅當預期值A和記憶體值V想要時,將記憶體值修改為並返回true,否則什麼都不做,並返回false.
1.Unsafe,是CAS的核心類,由於Java方法無法直接訪問底層系統,需要通過本地(native)方法來訪問,Unsafe相當於一個後門,基於該類可以直接操作特定記憶體的資料。
2.變數valueOffset,表示該變數值在記憶體中的偏移地址,因為Unsafe就是根據記憶體偏移地址獲取資料的
3.變數value用volatile修飾,保證了多執行緒之間的記憶體可見性。
CAS缺點:即ABA問題
Q:如果變數V初次讀取的時候是A,並且在準備賦值的時候檢查到他仍是A,那能說明他的值沒有被其他執行緒修改過了嗎?
如果在這段時間曾經被改成B,然後又改回A,那CAS操作就會誤認為他從來沒有被修改過。
針對這種情況,Java併發包中提供了一個帶有標記的原子引用類AtomicStampedReference,他可以通過控制變數值的版本 來保證CAS的正確性。
以上就是一些粗略的知識點,詳細的還在學習中。。。。。。。
=======還在學習中,學的東西還很多=======