分段锁
JDK1.7时ConcurrentHashMap使用的是分段锁来实现线程安全的。
设计的核心思想
数据分片与独立锁
将整个哈希表划分为多个逻辑段(Segment),每个段都独立维护一个哈希桶数组并配备一把锁(ReentrantLock)
优点:可以并行操作不同逻辑段
读写分离优化
读操作无锁:依赖volatile修饰HashEntry.value和next指针保证可见性。
写操作分段锁:对目标段加锁。
操作流程 -- 写
1、计算键的哈希值,通过hash%segments.length确定目标段。
2、获取目标段的锁。
3、在段内的哈希桶中插入或更新节点。
4、释放锁。
CAS+synchronized
JDK1.8之后使用的是CAS+synchronized。
分段锁的缺点
1、锁的粒度还是不够小。
2、内存分配不均,段数量固定可能导致部分段负载过高,其他段空闲。
设计的核心思想
以桶为粒度
从段级缩小到桶级,并发度显著提升。
操作流程 -- 写
1、计算键的哈希值,通过hash%entry.length确认目标桶。
2、如果发现目标桶为null,则使用CAS保证线程安全;如果发现目标桶不为null,则使用synchronized。
3、更新或插入
4、释放锁