ConcurrentHashMap精简篇(无源码)

目录

Concurrent HashMap(数组+链表+红黑树)

ConcurrentHashMap.transfer()多线程扩容

ConcurrentHashMap扩容源码分析总结:

ConcurrentHashMap.put()过程总结((hash值)& (数组长度-1)确定位置)

ConcurrentHashMap.get()(hash值)& (数组长度-1)确定位置)扩容时可以get】

ConcurrentHashMap.size()

Jdk1.7ConcurrentHashMap(分段上锁)

JDK1.7和JDK1.8ConcurrentHashMap区别:


Concurrent HashMap(数组+链表+红黑树)

ConcurrentHashMap不允许key或value为null值。

 重要的属性sizeCtl

  • -1代表正在初始化
  • -N 表示有N-1个线程正在进行扩容操作
  • 0代表hash表还没有被初始化
  • >0 代表扩容阈值,它的值始终是当前ConcurrentHashMap容量的0.75倍

数组table中节点类型和Hash值关系(区分节点的类型就是用Hash值区分的):

  • Node----》Hash值>=0
  • ForwardingNod-----》用Hash值=MOVED=-1标记
  • TreeBin ------》用Hash值=TREEBIN=-2,TreeBin里是TreeNode集合,是红黑树结构
  • ReservationNode:数组中占位临时节点----》Hash值=RESERVED=-3

ForwardingNode的情况(表示扩容时处理完毕的节点)

  • 扩容时,老数组某个位置没有元素,则标记为ForwardingNode节点(此时无需处理所以直接标记处理完毕)
  • 扩容时,已迁移完毕,则标记为ForwardingNode节点

初始化方法

初始化方法主要应用了关键属性sizeCtl 如果这个值〈0,表示其他线程正在进行初始化,就放弃这个操作。如果获得了初始化权限,就用CAS方法将sizeCtl置为-1,防止其他线程进入。

初始化:默认初始化容量为16,加载因子为0.75的数组。将sizeCtl的值改为0.75*n作为触发扩容的阈值

ConcurrentHashMap.transfer()多线程扩容

基本认识:

每个线程扩容时,根据cpu数量确定要扩容的步长,cpu数量越多,那每个线程需要处理的步长越小,最小步长为16

假设原数组长度为64:

扩容时transferIndex记录了下一个线程需要处理的最大边界,

每当来一个线程来帮助扩容时,范围计算公式:[transferIndex-计算出的步长,transferIndex)

transferIndex的初始值=数组长度=n

第一个参与扩容的线程,[64

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值