欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 社会 > ConcurrentHashMap

ConcurrentHashMap

2025/7/11 5:47:01 来源:https://blog.csdn.net/chi_666/article/details/145955885  浏览:    关键词:ConcurrentHashMap

ConcurrentHashMap 是 Java 中用于在多线程环境下高效存储和操作键值对的哈希表实现,下面从基本概念、底层数据结构、线程安全机制、关键方法、性能特点以及使用场景几个方面详细介绍:

基本概念

ConcurrentHashMapjava.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 可以支持多个线程同时进行读写操作,并发性能较高。
  • 空间开销:相比于 HashMapConcurrentHashMap 为了保证线程安全,会有一定的空间开销,例如分段锁(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 类似,但它在多线程环境下可以保证线程安全。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词