源码所属版本为jdk1.8
ConcurrentHashMap:
public V put(K key, V value) {
return putVal(key, value, false);
}
这是put方法可以看到调用的是putVal方法。
final V putVal(K key, V value, boolean onlyIfAbsent) {
//key值和value值都不能为空
if (key == null || value == null) throw new NullPointerException();
int hash = spread(key.hashCode());//让高位的hash值参与运算以降低碰撞概率
int binCount = 0;
for (Node<K,V>[] tab = table;;) {//死循环
Node<K,V> f; int n, i, fh;
if (tab == null || (n = tab.length) == 0)//判断是否初始化
tab = initTable();//初始化
else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {//判断表里第i个节点是否为空
if (casTabAt(tab, i, null,
new Node<K,V>(hash, key, value, null)))//通过CAS直接添加到第i个节点中
break; // no lock when adding to empty bin
}
else if ((fh = f.hash) == MOVED)//判断是否是扩容节点
tab = helpTransfer(tab, f);//帮助扩容
else {//该节点已经有值
V oldVal = null;
synchronized (f) {//对表里的第i个的头节点加锁
if (tabAt(tab, i) == f) {//判断是否是头节点
if (fh >= 0) {//判断头节点的hash值是否大于等于0
binCount = 1;//链表里节点的数量
for (Node<K,V> e = f;; ++binCount) {//死循环
K ek;
if (e.hash == hash &&
((ek = e.key) == key ||
(ek != null && key.equals(ek)))) {//判断现在的key值与链表里的key值相等
oldVal = e.val;
if (!onlyIfAbsent)
e.val = value;//直接覆盖
break;
}
Node<K,V> pred = e;
if ((e = e.next) == null) {//如果下个节点为空,直接赋值。
pred.next = new Node<K,V>(hash, key,
value, null);
break;
}
}
}
else if (f instanceof TreeBin) {//树节点
Node<K,V> p;
binCount = 2;
if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
value)) != null) {//插入到红黑树中如果有返回值则改key值已存在覆盖value值
oldVal = p.val;
if (!onlyIfAbsent)
p.val = value;
}
}
}
}
if (binCount != 0) {//链表节点数量不等于0
if (binCount >= TREEIFY_THRESHOLD)//判断是否大于等于8
treeifyBin(tab, i);//转换成红黑树
if (oldVal != null)
return oldVal;
break;
}
}
}
addCount(1L, binCount); // 统计节点个数,检查是否需要resize
return null;
}