1. 程式人生 > >為什麼 ConcurrentHashMap 的讀操作不需要加鎖?

為什麼 ConcurrentHashMap 的讀操作不需要加鎖?

# 前言 我們知道,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) {