為什麼 ConcurrentHashMap 的讀操作不需要加鎖?
阿新 • • 發佈:2020-12-21
# 前言
我們知道,ConcurrentHashmap(1.8)這個併發集合框架是執行緒安全的,當你看到原始碼的get操作時,會發現get操作全程是沒有加任何鎖的,這也是這篇博文討論的問題——為什麼它不需要加鎖呢?
# 為什麼 ConcurrentHashMap 的讀操作不需要加鎖?
## ConcurrentHashMap的簡介
“我想有基礎的同學知道在jdk1.7中是採用Segment + HashEntry + ReentrantLock的方式進行實現的,而1.8中放棄了Segment臃腫的設計,取而代之的是採用Node + CAS + Synchronized來保證併發安全進行實現。
JDK1.8的實現降低鎖的粒度,JDK1.7版本鎖的粒度是基於Segment的,包含多個HashEntry,而JDK1.8鎖的粒度就是HashEntry(首節點)
JDK1.8版本的資料結構變得更加簡單,使得操作也更加清晰流暢,因為已經使用synchronized來進行同步,所以不需要分段鎖的概念,也就不需要Segment這種資料結構了,由於粒度的降低,實現的複雜度也增加了
JDK1.8使用紅黑樹來優化連結串列,基於長度很長的連結串列的遍歷是一個很漫長的過程,而紅黑樹的遍歷效率是很快的,代替一定閾值的連結串列,這樣形成一個最佳拍檔
![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/be74aa6757ed4d489f62b0bc75d5082d~tplv-k3u1fbpfcp-watermark.image)
## get操作原始碼
首先計算hash值,定位到該table索引位置,如果是首節點符合就返回
如果遇到擴容的時候,會呼叫標誌正在擴容節點ForwardingNode的find方法,查詢該節點,匹配就返回
以上都不符合的話,就往下遍歷節點,匹配就返回,否則最後就返回null
```
//會發現原始碼中沒有一處加了鎖
public V get(Object key) {