ConcurentHashMap解析

本文详细介绍了ConcurrentHashMap的内部实现,包括其数据结构(数组+链表+红黑树)、不可修改的负载因子(0.75)、Node对象的hash字段的意义以及sizeCtl字段的作用。内容涵盖并发安全的写入机制、扩容过程中的线程安全策略以及在红黑树状态下读写线程的同步控制。通过对扩容条件、线程协同扩容、旧链表迁移的标记和读写线程处理的讨论,揭示了ConcurrentHashMap高效并发特性的背后逻辑。
摘要由CSDN通过智能技术生成

1、并发Map存储的数据结构

数组+链表+红黑树,存储数据的单元是Node结构,Node结构有key,value以及指向下一个Node的引用,还有hash字段

2、并发Map的负载因子可以修改吗?可以指定吗?

普通的 HashMap 的负载因子可以修改,但是 ConcurrentHashMap 不可以,因为它的负载因子使用final关键字修饰,值是固定的 0.75

3、Node对象的hash字段在一般情况下,必须是>=0,为什么?

散列表在扩容的时候,会触发一个迁移数据的过程,把原表的数据迁移到扩容后的散列表的逻辑

如果 Node.hash = -1,表示当前节点是 ForWardingNode节点(表示已经被迁移的节点)。
如果 Node.hash = -2,表示当前节点已经树化,且当前节点为 TreeBin 对象,TreeBin 对象代理操作红黑树。
如果 Node.hash > 0,表示当前节点是正常的 Node 节点,可能是链表,或者单个 Node。

4、简述 ConcurrentHashMap 中 sizeCtl 字段的作用

sizeCtl = -1,表示正在初始化。有线程正在对当前散列表(table) 进行初始化操作。
ConcurrentHashMap 的散链表是延迟初始化的,在并发条件下必须确保只能初始化一次,所以 sizeCtl == -1 就相当于一个"标识锁",防止多个线程去初始化散列表。

具体初始化操作就是在initTable()方法中,会通过 CAS 的方式去修改 sizeCtl 的值为 -1,表示已经有线程正在对散链表进行初始化,其他线程不可以再次初始化,只能等待!
如果 CAS 修改 sizeCtl = -1 操作成功的线程,可以接着执行对散链表初始化的逻辑。而 CAS 修改失败的线程,在

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值