ConcurrentHashMap
- 其他
- 2025-09-21 09:33:01

ConcurrentHashMap 是 Java 中用于在多线程环境下高效存储和操作键值对的哈希表实现,下面从基本概念、底层数据结构、线程安全机制、关键方法、性能特点以及使用场景几个方面详细介绍:
基本概念ConcurrentHashMap 是 java.util.concurrent 包下的一个类,它继承自 AbstractMap 类并实现了 ConcurrentMap 接口。与 HashMap 不同,ConcurrentHashMap 是线程安全的,在多线程环境下可以高效地进行并发操作,避免了 HashMap 在多线程环境下可能出现的数据不一致和线程安全问题。
底层数据结构 JDK 1.7 分段锁机制:ConcurrentHashMap 使用分段锁(Segment)来实现线程安全。整个哈希表被分成多个 Segment,每个 Segment 类似于一个小的 HashMap,它继承自 ReentrantLock,可以独立加锁。不同的 Segment 可以被不同的线程同时访问,从而提高并发性能。数据结构:每个 Segment 内部包含一个哈希表,由数组和链表组成。 JDK 1.8 CAS + synchronized:摒弃了分段锁机制,采用 CAS(Compare-And-Swap,比较并交换)和 synchronized 来保证线程安全。数据结构:底层数据结构是数组 + 链表 + 红黑树。当链表长度超过 8 且数组长度大于 64 时,链表会转换为红黑树,以提高查找效率。 线程安全机制 JDK 1.7 每个 Segment 都有自己独立的锁,不同的 Segment 可以并行操作。当一个线程访问某个 Segment 时,会对该 Segment 加锁,其他线程可以同时访问其他 Segment,从而提高并发度。 JDK 1.8 CAS 操作:在插入元素时,首先会使用 CAS 操作尝试更新数组中的节点,如果 CAS 操作成功,则插入成功;如果失败,则说明有其他线程在同时操作,会进入下一步处理。synchronized 锁:当发生哈希冲突时,会使用 synchronized 对链表或红黑树的头节点加锁,保证同一时刻只有一个线程可以对该链表或红黑树进行操作。 关键方法 put(K key, V value) 作用:将指定的键值对插入到 ConcurrentHashMap 中。实现:在 JDK 1.8 中,首先计算键的哈希值,找到对应的桶位置。如果桶为空,使用 CAS 操作将新节点插入;如果桶不为空,对桶的头节点加锁,遍历链表或红黑树,若键已存在则更新值,否则插入新节点。 get(Object key) 作用:根据指定的键获取对应的值。实现:计算键的哈希值,找到对应的桶位置,然后遍历链表或红黑树查找键对应的值。由于 get 操作不需要加锁,所以性能较高。 size() 作用:返回 ConcurrentHashMap 中键值对的数量。实现:在 JDK 1.8 中,size 方法会先尝试使用无锁的方式统计元素数量,如果失败则会加锁统计。 性能特点 高并发性能:由于采用了分段锁(JDK 1.7)或 CAS + synchronized(JDK 1.8)的机制,ConcurrentHashMap 可以支持多个线程同时进行读写操作,并发性能较高。空间开销:相比于 HashMap,ConcurrentHashMap 为了保证线程安全,会有一定的空间开销,例如分段锁(JDK 1.7)和额外的 CAS 操作。 使用场景 多线程环境下的缓存:在多线程环境中,如果需要使用缓存来存储数据,ConcurrentHashMap 是一个不错的选择,它可以保证线程安全,同时具有较高的并发性能。共享数据存储:当多个线程需要共享一个哈希表时,使用 ConcurrentHashMap 可以避免数据不一致和线程安全问题。 示例代码 import java.util.concurrent.ConcurrentHashMap; public class ConcurrentHashMapExample { public static void main(String[] args) { ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>(); // 插入键值对 map.put("apple", 1); map.put("banana", 2); map.put("cherry", 3); // 获取值 Integer value = map.get("banana"); System.out.println("Value of banana: " + value); // 遍历键值对 for (ConcurrentHashMap.Entry<String, Integer> entry : map.entrySet()) { System.out.println(entry.getKey() + ": " + entry.getValue()); } // 删除键值对 map.remove("cherry"); System.out.println("After removing cherry, size: " + map.size()); } }通过上述代码可以看到,ConcurrentHashMap 的使用方式与 HashMap 类似,但它在多线程环境下可以保证线程安全。
ConcurrentHashMap由讯客互联其他栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“ConcurrentHashMap”