ConcurrentHashMap源码剖析

前言锁优化有一个很重要的思路,就是拆分锁的粒度,类似于分布式锁优化的实践,把一份数据拆分为多份数据,对每一份数据片段来加锁,这样就可以提升多线程并发的效率HashMap底层不就是一个数组的数据结构么?如果你要完全保证里的并发安全,如果你每次对数组做一些put、resize、get的操作的时候,你都是加锁,synchronized好了,此时就会导致并发性能非常的低下所有的线程读写hash...
摘要由CSDN通过智能技术生成

前言

锁优化有一个很重要的思路,就是拆分锁的粒度,类似于分布式锁优化的实践,把一份数据拆分为多份数据,对每一份数据片段来加锁,这样就可以提升多线程并发的效率

HashMap底层不就是一个数组的数据结构么?如果你要完全保证里的并发安全,如果你每次对数组做一些put、resize、get的操作的时候,你都是加锁,synchronized好了,此时就会导致并发性能非常的低下

所有的线程读写hashmap的过程都是串行化的,hashtable,就是采用的这种做法

读写锁,大量的读锁和写锁冲突的时候,也会导致多线程并发的效率大大的降低,也不行。

ConcurrentHashMap,分段加锁,把一份数据拆分为多个segment,对每个段设置一把小锁,put操作,仅仅只是锁掉你的那个数据一个segment而已,锁一部分的数据,其他的线程操作其他segmetn的数据,跟你是没有竞争的。大大减少了锁竞争,从而提高了性能。

put()剖析

int hash = spread(key.hashCode());

对key获取了hashCode,调用了spread算法,获取到了一个hash值

    static final int spread(int h) {

        return (h ^ (h >>> 16)) & HASH_BITS;

}

他相当于是把hash值的高低16位都考虑到后面的hash取模算法里,这样就可以把hash值的高低16位的特征都放到hash取模算法来运算,有助于尽可能打散各个key在不同的数组的位置,降低hash冲突的概率

刚开始,table是null的话,此时就要初始化这个table。

U.compareAndSwapInt(this, SIZECTL, sc, -1):CAS操作,sizeCtl = -1

初始化一个table数组,默认的大小就是16

tabAt(tab, i = (n - 1) & hash) --》return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);

i = (n - 1) & hash,这个就是hash取模的算法,定位的算法。定位出来的位置,传递给了tabAt()函数进行volatile读。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值