目录
put方法
public V put(K key, V value) {
return putVal(key, value, false);
}
final V putVal(K key, V value, boolean onlyIfAbsent) {
if (key == null || value == null) throw new NullPointerException();
// 其中 spread 方法会综合高位低位, 具有更好的 hash 性
int hash = spread(key.hashCode());
int binCount = 0;
for (Node<K,V>[] tab = table;;) {
// f 是链表头节点
// fh 是链表头结点的 hash
// i 是链表在 table 中的下标
Node<K,V> f; int n, i, fh;
// 要创建 table
if (tab == null || (n = tab.length) == 0)
// 初始化 table 使用了 cas, 无需 synchronized 创建成功, 进入下一轮循环
tab = initTable();
// 要创建链表头节点
else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
// 添加链表头使用了 cas, 无需 synchronized
if (casTabAt(tab, i, null,
new Node<K,V>(hash, key, value, null)))
break;
}
// 帮忙扩容
else if ((fh = f.hash) == MOVED)
// 帮忙之后, 进入下一轮循环
tab = helpTransfer(tab, f);
else {
V oldVal = null;
// 锁住链表头节点
synchronized (f) {
// 再次确认链表头节点没有被移
JDK8 HashMap并发控制详解

本文详细介绍了JDK8中HashMap的put方法、bincount、get函数、initTable及锁实现。在put方法中,当table不存在时,会通过initTable初始化;存在时,根据hash找到桶,尝试CAS插入或扩容。bincount使用类似LongAdder的机制维护计数,get函数通过hash值定位节点,处理扩容或红黑树查找。initTable采用双重检查确保线程安全初始化。JDK8的锁实现放弃了JDK7的分段锁,转而使用CAS配合synchronized实现并发控制。
最低0.47元/天 解锁文章
2520

被折叠的 条评论
为什么被折叠?



