ConcurrentHashMap 原理分析和使用实践

ConcurrentHashMap 原理分析

ConcurrentHashMap 是 Java 中提供的一个线程安全的哈希表。相比于 Hashtable 和同步包装的 HashMap(通过 Collections.synchronizedMap 获得),ConcurrentHashMap 提供了更高的并发性能。

分段锁(Segmentation)

在 Java 7 及之前,ConcurrentHashMap 使用了分段锁的概念,通过将内部数据分为一段一段(Segment),来减少锁的竞争。每个 Segment 维护了一个哈希表,并且每个 Segment 是独立锁定的。当进行插入、删除和更新操作时,只需要锁定相关的 Segment,而不需要锁定整个哈希表。

锁粒度进一步细化(Java 8)

在 Java 8 中,ConcurrentHashMap 的实现被进一步优化。Java 8 放弃了原有的 Segment 方式,转而使用了一种基于节点的锁机制,这种机制进一步提高了并发性。主要改进包括:

  • 使用了一种称为“synchronized”和“CAS”(比较并交换)操作的机制来管理对单个桶(bucket)的写入。
  • 读操作可以完全并行,因为它们不需要锁定。只有在写入的时候,才会锁定相关的桶,这减少了锁的范围和锁竞争。
  • 链表转换为红黑树:为了改善在高哈希碰撞情况下的性能,链表结构被动态地替换为红黑树结构。

ConcurrentHashMap 使用实践

创建 ConcurrentHashMap
ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
常用方法
  • put(key, value):将指定的值与此映射中的指定键关联。
  • get(key):返回指定键所映射的值。
  • remove(key):从此映射中移除键的映射关系。
  • putIfAbsent(key, value):如果指定的键尚未与某个值关联,则将其与给定值关联。
  • computeIfAbsent(key, mappingFunction):如果指定键的值为 null,尝试使用给定的映射函数计算其值。
  • forEach(action):对 ConcurrentHashMap 的每个元素执行给定的操作。
示例代码
ConcurrentHashMap<Integer, String> chm = new ConcurrentHashMap<>();
chm.put(1, "Java");
chm.put(2, "Python");
chm.put(3, "Go");

String value = chm.get(1); // "Java"

chm.forEach((key, val) -> System.out.println(key + " => " + val));

String result = chm.computeIfAbsent(4, k -> "JavaScript");
System.out.println(result); // "JavaScript"
并发操作

由于 ConcurrentHashMap 是为高并发环境设计的,你可以在多个线程中安全地执行更新操作,而不需要外部同步。

ExecutorService executor = Executors.newFixedThreadPool(2);
ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();

Runnable task = () -> {
    map.putIfAbsent(Thread.currentThread().getName(), "value");
};

executor.submit(task);
executor.submit(task);

executor.shutdown();

在上面的例子中,即使多个线程尝试更新 ConcurrentHashMapputIfAbsent() 方法保证了每个键只被赋值一次。

注意事项

  • 虽然 ConcurrentHashMap 的读取操作非常快,但写入操作可能会稍微慢一些,因为它们涉及同步。
  • 在迭代元素时,迭代器只能反映 ConcurrentHashMap 在迭代器创建时或在迭代开始时的状态。
  • ConcurrentHashMap 不允许使用 null 键或 null 值,因为多个 null 值可能导致无法区分返回值是 map 中的一个条目,还是 map 中没有该键。
  • ConcurrentHashMap 提供了一系列原子操作,这意味着你不需要用同步来组合多个方法调用。

ConcurrentHashMap 是解决并发编程中的共享资源问题的强大工具。恰当使用它,可以在多线程环境下安全高效地管理共享的可变数据。

  • 23
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序员爱学习

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

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

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

打赏作者

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

抵扣说明:

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

余额充值