currenthashmap详解

本文详细解析了ConcurrentHashMap在1.7和1.8版本中的实现机制,包括segment数组分段锁、CSA和Synchronized机制的应用,以及底层数据结构如数组、链表和红黑树的使用。特别关注了hash算法、红黑树转换条件和sizeCtl控制标识符的作用。

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

1.7实现
采用segment数组分段锁机制,实现并发的更新,底层采用数组+链表+红黑树
每一个segment相当于一个hashMap
1.8实现
采用CSA和Synchronized机制,底层同样采用了数组+链表+红黑树
初始化:initTable()
当tab==null || tab.length()==0时 while循环中执行;
table只在put方法中初始化1次,初始化的线程将sizeCtl设置为-1,
U.compareAndSwapInt(this, SIZECTL, sc, -1)
其他线程判断sizeClt<0,则THhread.yield()让出时间片


putVal()方法
1.hash算法
static final int spread(int h) {return (h ^ (h >>> 16)) & HASH_BITS;}
2.table中定位索引位置,n是table的大小  int index = (n - 1) & hash
3.获取table中对应索引的元素f
Doug Lea采用Unsafe.getObjectVolatile来获取,为什么不直接从每个线程的table[index]中取?
因为每个线程中取到的table的元素,有可能不是最新的,而Unsafe.getObjectVolatile()可以直接从内存中获取最新的元素
【红黑树】
如果链表结构中元素超过TREEIFY_THRESHOLD阈值,默认为8个,则把链表转化为红黑树,提高遍历查询效率,效率为log(n)
链表转树阈值:8
树转链表阈值:6
树根节点的hash值为:-2
【sizeCtl】
sizeCtl是控制标识符,不同的值表示不同的意义。
负数代表正在进行初始化或扩容操作
-1代表正在初始化
-N 表示有N-1个线程正在进行扩容操作
正数或0代表hash表还没有被初始化,这个数值表示初始化或下一次进行扩容的大小,类似于扩容阈值。它的值始终是当前ConcurrentHashMap容量的0.75倍,这与loadfactor是对应的。实际容量>=sizeCtl,则扩容(sc = n - (n >>> 2); //无符号右移2位,此即0.75*n )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值