ConcurrentHashMap 實(shí)現(xiàn)原理
- HashMap 是非線程安全的,HashTable 是線程安全的,在不考慮性能問題的時(shí)候,多線程下可以使用 Hashtable 與 Collections.synchronizedMap(),這兩種方式基本都是對(duì)整個(gè) hash 表結(jié)構(gòu)做鎖定操作,這表明在鎖定期間別的線程就需要等待,無疑性能不高,HashTable 容器在競爭激烈的并發(fā)環(huán)境下效率低下,因?yàn)樗性L問 HashTable 的線程都必須競爭同一把鎖
- ConcurrentHashMap 使用鎖分段技術(shù),將數(shù)據(jù)分成一段一段的存儲(chǔ),給每一段數(shù)據(jù)配置一把鎖,當(dāng)一個(gè)線程占用鎖訪問其中一段數(shù)據(jù)時(shí),其他段的數(shù)據(jù)也能被其它線程訪問
- 但有些方法需要跨段,如 size() 它可能需要鎖定整個(gè)表而不是僅僅某個(gè)段,這需要按順序鎖定所有段,操作完畢后又按順序鎖定所有段的鎖
- ConcurrentHashMap 是由 Segment 數(shù)組結(jié)構(gòu)和 HashEntry 數(shù)組結(jié)構(gòu)組成:
- Segment 是一種 ReentrantLock
- HashEntry 用于存儲(chǔ)鍵值對(duì)數(shù)據(jù)
- 一個(gè) ConcurrentHashMap 里包含一個(gè) Segment 數(shù)組,Segment 的結(jié)構(gòu)與 HashMap 類似,是一種鏈表散列數(shù)據(jù)結(jié)構(gòu),一個(gè) Segment 包含一個(gè) HashEntry 數(shù)組,每個(gè) HashEntry 是一個(gè)鏈表結(jié)構(gòu)的元素
- 每個(gè) Segment 維護(hù)著一個(gè) HashEntry 數(shù)組里的元素,當(dāng)要對(duì) HashEntry 的數(shù)據(jù)進(jìn)行修改時(shí),就必須先獲得對(duì)應(yīng)的 Segement 鎖
