JDK 1.6 与 1.8 中的 ConcurrentHashMap 学习

本文详细解析了JDK1.8中ConcurrentHashMap的实现原理及改进,包括取消segment、链表转红黑树等特性,介绍了get、put等核心方法的工作流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考资料:

1、JDK1.8逐字逐句带你理解ConcurrentHashMap
https://blog.youkuaiyun.com/u012403290/article/details/67636469

2、Java并发编程总结4——ConcurrentHashMap在jdk1.8中的改进
https://www.cnblogs.com/everSeeker/p/5601861.html

3、jdk1.8中ConcurrentHashMap的实现原理
https://blog.youkuaiyun.com/fjse51/article/details/55260493

4、ConcurrentHashMap源码分析_JDK1.8版本
https://segmentfault.com/a/1190000009001468

5、多线程-ConcurrentHashMap(JDK1.8)
https://www.cnblogs.com/lujiango/p/7580558.html


ConcurrentHashMap

使用 segment (继承 ReentrantLock) 和 volatile 来保证线程安全性

segment 的数量为 16,每个 segment 中桶(HashEntry[])的数量可以增加,桶中放的是 由 HashEntry 组成的链表;count 表示 segment 中元素的数量, modCount 统计导致结构变化操作的次数(put、remove、replace、clear)

HashEntry 中的 value 变量 和 指向下一个节点的引用变量 next 都是使用 volatile 关键字进行修饰的,以此保证有序性和可见性

  • get() 方法不加锁,先找 segemnt 再找 桶

  • put() 方法要加锁,插入之前先判断 count 与阈值的关系,有需要的话则进行扩容处理(桶的容量扩容两倍)

put、remove、replace、clear 操作都要加锁

  • size() 先尝试两次不加锁的统计各个 segment 中的 count,如果结果不一致,则采用对全部 segment 加锁的方式统计

JDK 1.8 中的 ConcurrentHashMap

使用 synchronized 和 volatile 关键字来保证线程安全

取消 segment ,当桶中 链表 长度大于 8 时,将链表转换为 RBTree

  • get()方法不加锁

  • put()方法:

如果桶是空的,则初始化桶,并采用 CAS 操作将元素放在链表的首位

如果桶非空,则通过使用 synchronized 锁住 链表的第一个节点(以此来锁住整个桶),再使用 Unsafe 类的 CAS 操作将元素放在链表的末尾


JDK 1。8 中 ConcurrentHashMap 中使用 synchronized 替代 Segment ,使得锁的粒度更加精细,以此提高程序的性能


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值