學習ConcurrentHashMap併發寫機制
阿新 • • 發佈:2020-03-16
# 1. 前言
上篇文章講了 Unsafe 類中 CAS 的實現,其實是在為這篇文章打基礎。不太熟悉的小夥伴請移步[Unsafe 中 CAS 的實現](https://mp.weixin.qq.com/s/7u63bPY_N5-0192akhuXjg)。本篇文章主要基於 `OpenJDK8` 來做原始碼解析。
# 2. 原始碼
ConcurrentHashMap 基於 HashMap 實現。
JDK1.7 和 JDK1.8 作為併發容器在實現上是有差別的。JDK1.7 通過 Segment 分段鎖實現,而 JDK1.8 通過 CAS+synchronized 實現。
## 2.1 ConcurrentHashMap 幾個重要方法
在 ConcurrentHashMap 中使用了 unSafe 方法,通過直接操作記憶體的方式來保證併發處理的安全性,使用的是硬體的安全機制。
```java
private static final sun.misc.Unsafe U;
private static final long SIZECTL;
private static final long TRANSFERINDEX;
private static final long BASECOUNT;
private static final long CELLSBUSY;
private static final long CELLVALUE;
private static final long ABASE;
private static final int ASHIFT;
static {
try {
U = sun.misc.Unsafe.getUnsafe();
Class k = ConcurrentHashMap.class;
SIZECTL = U.objectFieldOffset
(k.getDeclaredField("sizeCtl"));
TRANSFERINDEX = U.objectFieldOffset
(k.getDeclaredField("transferIndex"));
BASECOUNT = U.objectFieldOffset
(k.getDeclaredField("baseCount"));
CELLSBUSY = U.objectFieldOffset
(k.getDeclaredField("cellsBusy"));
Class ck = CounterCell.class;
CELLVALUE = U.objectFieldOffset
(ck.getDeclaredField("value"));
Class ak = Node[].class;
ABASE = U.arrayBaseOffset(ak);
int scale = U.arrayIndexScale(ak);
if ((scale & (scale - 1)) != 0)
throw new Error("data type scale not a power of two");
ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
} catch (Exception e) {
throw new Error(e);
}
}
stati