JDK8之ConcurrentHashMap源码刨析实现原理

ConcurrentHashMap源码刨析

ConcurrentHashMap相比于HashMap来讲,是线程安全的。底层的数据结构相同,都是数组+链表+红黑树。

Segment分段锁技术

因Segment继承ReentrantLock加锁,所以ConcurrentHashMap支持并发操作。

  static class Segment<K,V> extends ReentrantLock implements Serializable {
        private static final long serialVersionUID = 2249069246763182397L;
        final float loadFactor;
        Segment(float lf) { this.loadFactor = lf; }
    }

线程安全

简单理解就是,ConcurrentHashMap 是一个 Segment 数组,Segment 通过继承ReentrantLock 来进行加锁,所以每次需要加锁的操作锁住的是一个 segment,这样只要保证每个 Segment 是线程安全的,也就实现了全局的线程安全。

并行度(默认 16)

concurrencyLevel:并行级别、并发数、Segment 数,怎么翻译不重要,理解它。默认是 16, 也就是说 ConcurrentHashMap 有 16 个 Segments,所以理论上,这个时候,最多可以同时支持 16 个线程并发写,只要它们的操作分别分布在不同的 Segment 上。这个值可以在初始化的时候设置为其他值,但是一旦初始化以后,它是不可以扩容的。再具体到每个 Segment 内部,其实每个 Segment 很像之前介绍的 HashMap,不过它要保证线程安全,所以处理起来要麻烦些。 Java8 对 ConcurrentHashMap 进行了比较大的改动,Java8 也引入了红黑树。

并发

减小锁粒度

减小锁粒度是指缩小锁定对象的范围,从而减小锁冲突的可能性,从而提高系统的并发能力。减小锁粒度是一种削弱多线程锁竞争的有效手段,这种技术典型的应用是 ConcurrentHashMap(高性能的 HashMap)类的实现。对于 HashMap 而言,最重要的两个方法是get 与set 方法,如果我们对整个 HashMap 加锁,可以得到线程安全的对象,但是加锁粒度太大。Segment 的大小也被称为ConcurrentHashMap 的并发度。

分段锁

ConcurrentHashMap,它内部细分了若干个小的 HashMap,称之为段(Segment)。默认情况下一个ConcurrentHashMap 被进一步细分为 16 个段,既就是锁的并发度。
如果需要在 ConcurrentHashMap 中添加一个新的表项,并不是将整个 HashMap 加锁,而是首先根据hashcode 得到该表项应该存放在哪个段中,然后对该段加锁,并完成put 操作。在多线程环境中,如果多个线程同时进行put 操作,只要被加入的表项不存放在同一个段中,则线程间可以做到真正的并行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
JDK7中的ConcurrentHashMap是Java中的线程安全的哈希表实现,它支持高并发的读写操作。下面是对其码的简要介绍: 1. ConcurrentHashMap的内部结构: ConcurrentHashMap的内部结构由一个Segment数组和一个HashEntry数组组成。Segment是一种可重入锁,用于对HashEntry数组中的元素进行加锁操作。每个Segment维护了一个HashEntry数组的子集,不同的Segment之间可以并发地进行读写操作。 2. HashEntry的结构: HashEntry是ConcurrentHashMap中存储键值对的节点,它包含了键、值和一个指向下一个节点的引用。当多个键值对映射到同一个桶时,它们会形成一个链表。 3. ConcurrentHashMap的put操作: 当调用put方法向ConcurrentHashMap中插入键值对时,首先会根据键的哈希值找到对应的Segment,然后在该Segment中进行插入操作。如果插入的键已经存在,则会更新对应的值;如果插入的键不存在,则会创建一个新的节点并插入到链表的头部。 4. ConcurrentHashMap的get操作: 当调用get方法从ConcurrentHashMap中获取值时,首先会根据键的哈希值找到对应的Segment,然后在该Segment中进行查找操作。如果找到了对应的节点,则返回节点的值;如果没有找到,则返回null。 5. ConcurrentHashMap的扩容: 当ConcurrentHashMap中的元素数量达到一定阈值时,会触发扩容操作。扩容过程会创建一个新的Segment数组和HashEntry数组,并将原来的元素重新分配到新的数组中。在扩容过程中,读操作可以继续进行,而写操作会被阻塞。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

践者

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

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

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

打赏作者

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

抵扣说明:

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

余额充值