您当前的位置: 首页 >  容器

顧棟

暂无认证

  • 0浏览

    0关注

    227博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【JUC系列】并发容器之ConcurrentHashMap(JDK1.8版)扩容图解说明

顧棟 发布时间:2022-06-06 21:00:00 ,浏览量:0

ConcurrentHashMap(JDK1.8)扩容说明

文章目录
  • ConcurrentHashMap(JDK1.8)扩容说明
    • 扩容过程
      • 触发条件
      • 基本原理
      • 步骤
        • case1:当前的任务是整个数组扩容的最后一个任务或者扩容冲突。
        • case2:该桶为空即Node数组i下标中为null。
        • case3:该桶(Node数组i下标的元素)已经完成迁移。
        • case4:该桶还未迁移,根据桶首结点的hash值进行链表迁移或红黑树迁移。
      • 图解

扩容过程 触发条件

第一种场景在新增结点的时候,在addCount中检查元素个数时,若到达扩容阈值时,若数组长度小于64会调用tryPresize对Node数组进行2倍扩容transfer方法对结点的位置进行重分配。

第二种场景是在新增结点的时候,在当桶中链表结点数超过8个,会调用treeifyBin尝试进行将链表转为红黑树,但是若数组小于64,则也会对Node数组进行扩容,不链表转为红黑树。

基本原理

新建一个Node数组,其长度为旧数组长度的2倍,然后将旧的元素迁移到新数组中。

可以有一个或多个线程一起进行数据迁移,单核不支持多线程并行迁移。

迁移的过程中,旧数组的长度是N,每个线程扩容一段,一段的长度使用遍历stride(步长)来表示,为了降低资源竞争频率,stride最小的范围长度是16。transferIndex表示整个数组扩容的进度,每个调用tranfer的线程会对当前旧table中[transferIndex-stride, transferIndex-1]位置的结点进行迁移,不过是倒叙的方式进行的。

步骤

具体实现主要集中在transfer(Node[] tab, Node[] nextTab)方法中。

  1. 计算出stride的值 MIN_TRANSFER_STRIDE是16。

    if ((stride = (NCPU > 1) ? (n >>> 3) / NCPU : n)             
关注
打赏
1663402667
查看更多评论
0.0402s