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)方法中。
-
计算出stride的值
MIN_TRANSFER_STRIDE
是16。if ((stride = (NCPU > 1) ? (n >>> 3) / NCPU : n)
关注打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?