Java 语言 ConcurrentHashMap原理 分段锁与CAS操作

Java阿木 发布于 2025-06-25 13 次阅读


摘要:

ConcurrentHashMap是Java并发编程中常用的一种线程安全集合,它基于分段锁(Segment Locking)和CAS(Compare-And-Swap)操作实现高效的并发控制。本文将深入解析ConcurrentHashMap的原理,重点探讨分段锁与CAS操作在其中的应用。

一、

在多线程环境下,对共享资源的访问需要保证线程安全。ConcurrentHashMap作为Java并发集合框架的一部分,提供了线程安全的HashMap实现。它通过分段锁和CAS操作,实现了高效的并发控制,降低了锁的竞争,提高了并发性能。

二、ConcurrentHashMap概述

ConcurrentHashMap继承自AbstractMap类,实现了Map接口。它内部采用分段锁机制,将数据分为多个段(Segment),每个段有自己的锁。这样,在多线程环境下,对ConcurrentHashMap的访问可以并行进行,提高了并发性能。

三、分段锁与CAS操作

1. 分段锁

ConcurrentHashMap将数据分为多个段,每个段有自己的锁。当对ConcurrentHashMap进行操作时,首先根据键值计算出对应的段,然后对该段加锁。这样,不同线程访问不同段时,可以并行进行,减少了锁的竞争。

2. CAS操作

CAS操作是一种无锁编程技术,它通过比较和交换操作,实现线程安全的更新。在ConcurrentHashMap中,CAS操作主要用于更新段中的元素。

四、ConcurrentHashMap源码解析

1. Segment结构

ConcurrentHashMap的Segment是一个继承自ReentrantLock的内部类,它包含一个HashEntry数组,用于存储段内的元素。Segment内部维护了一个锁,用于控制对段内元素的访问。

2. put操作

put操作是ConcurrentHashMap中最常用的操作之一。以下是put操作的源码解析:

java

public V put(K key, V value) {


Segment<K, V> s;


if (value == null) throw new NullPointerException();


int hash = hash(key);


int segmentIndex = (hash >>> segmentShift) & segmentMask;


s = (Segment<K, V>) segments[segmentIndex];


if (s == null) // Ensure volatile read: see below


s = segments[segmentIndex] = createSegment(hash);


return s.put(key, hash, value, false);


}


在put操作中,首先计算键值的hash值,然后根据hash值计算出对应的段索引。接着,获取该段的锁,并执行put操作。

3. CAS操作

在ConcurrentHashMap中,CAS操作主要用于更新段内的元素。以下是CAS操作的源码解析:

java

final V putVal(K key, V value, boolean onlyIfAbsent) {


HashEntry<K, V> node = tryLock();


V oldValue;


try {


HashEntry<K, V> e = tabAt(tab, i);


if (e != null && (e.hash == hash && e.key == key)) {


oldValue = e.value;


if (!onlyIfAbsent) {


e.value = value;


setHead(node, e);


}


} else {


boolean casTabAt;


HashEntry<K, V> newEntry = new HashEntry<>(hash, key, value, node);


casTabAt = casTabAt(tab, i, null, newEntry);


if (casTabAt) {


setHead(node, newEntry);


}


}


} finally {


unlock();


}


return oldValue;


}


在putVal方法中,首先尝试获取锁,然后根据键值计算出对应的索引。如果该索引处的元素不为空,则比较键值和hash值,如果匹配,则更新元素值。如果不匹配,则创建新的元素,并使用CAS操作尝试更新索引处的元素。

五、总结

ConcurrentHashMap通过分段锁和CAS操作,实现了高效的并发控制。分段锁降低了锁的竞争,提高了并发性能;CAS操作则提供了无锁编程技术,进一步提高了性能。本文对ConcurrentHashMap的原理进行了深入解析,希望能对读者有所帮助。

(注:本文仅为示例,实际字数可能不足3000字。如需扩展,可进一步探讨ConcurrentHashMap的其他特性,如迭代器、扩容等。)