Java ConcurrentHashMap 线程安全实现机制深度解析

ConcurrentHashMap 是 Java 并发包中高性能的线程安全哈希表实现,其线程安全设计经历了从 JDK 7 的分段锁到 JDK 8 的 CAS + synchronized 的演进。以下是其核心线程安全实现原理的全面剖析:

一、JDK 8 之前的实现(分段锁机制)

1. 分段锁(Segment)设计

final Segment<K,V>[] segments;  // 分段数组

static final class Segment<K,V> extends ReentrantLock {
   
   
    transient volatile HashEntry<K,V>[] table;  // 段内哈希表
    transient int count;  // 段内元素计数
}

工作机制

  • 将整个哈希表分成多个 Segment(默认16个)
  • 每个 Segment 独立加锁(继承 ReentrantLock)
  • 不同 Segment 可并发操作
  • 同一 Segment 操作需要获取锁

优点:锁粒度减小,并发度提升(最大并发数=Segment数)

二、JDK 8 及之后的实现(CAS + synchronized 优化)

1. 核心数据结构

transient volatile Node<K,V>[] table;        // 主哈希表
private transient volatile int sizeCtl;      // 控制标识符
private transient volatile CounterCell[] counterCells; // 并发计数

2. 关键线程安全技术

(1)CAS(Compare-And-Swap)操作
// 典型CAS操作示例(简化版)
static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i,
                                    Node<K,V> c, Node<K,V> v) {
   
   
    return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v);
}
  • 用于无锁化的状态变更(如:数组初始化、节点插入)
  • 通过 Unsafe 类直接操作内存
(2)精细化 synchronized 同步
  • 仅锁住单个哈希桶(链表头节点/树根节点)
  • 锁粒度从分段缩小到单个桶
synchronized (f) {
   
     // f是链表头节点
    // 处理链表/树的操作
}
(3)并发控制变量 sizeCtl
private transient volatile int sizeCtl;
  • 负数:表示表正在初始化或扩容
  • 0:默认初始值
  • 正数:下一次扩容的阈值

3. put操作线程安全实现流程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦幻南瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值