ConcurrentHashMap的源码分析-为什么要做高低位的划分
要想了解这么设计的目的,我们需要从ConcurrentHashMap的根据下标获取对象的算法来看,在putVal方法中1018行
(f = tabAt(tab, i = (n - 1) & hash)) == null
通过(n-1) & hash来获得在table中的数组下标来获取节点数据,【&运算是二进制运算符,1 & 1=1,其他都为0】
假设我们的table长度是16, 二进制是【0001 0000】,减一以后的二进制是 【0000 1111】
假如某个key的hash值=9,对应的二进制是【0000 1001】,那么按照(n-1) & hash的算法
0000 1111 & 0000 1001 =0000 1001 , 运算结果是9
当我们扩容以后,16变成了32,那么(n-1)的二进制是 【0001 1111】
仍然以hash值=9的二进制计算为例
0001 1111 & 0000 1001 =0000 1001 ,运算结果仍然是9
我们换一个数字,假如某个key的hash值是20,对应的二进制是【0001 0100】,仍然按照(n-1) & hash算法,分别在16为长度和32位长度下的计算结果
16位: 0000 1111 & 0001 0100=0000 0100
32位: 0001 1111 & 0001 0100 =0001 0100
从结果来看,同样一个hash值,在扩容前和扩容之后,得到的下标位置是不一样的,这种情况当然是不允许出现的,所以在扩容的时候就需要考虑,
而使用高低位的迁移方式,就是解决这个问题.
大家可以看到,16位的结果到32位的结果,正好增加了16.
比如 20 & 15=4 、20 & 31=20 ; 4-20 =16
比如 60 & 15=12 、60 & 31=28; 12-28=16
所以对于高位,直接增加扩容的长度,当下次hash获取数组位置的时候,可以直接定位到对应的位置。
这个地方又是一个很巧妙的设计,直接通过高低位分类以后,就使得不需要在每次扩容的时候来重新计算hash,极大提升了效率。
ConcurrentHashMap的源码分析-为什么要做高低位的划分相关推荐
- HashMap与ConcurrentHashMap万字源码分析
HashMap与ConcurrentHashMap`源码解析 JDK版本:1.7 & 1.8 开发中常见的数据结构有三种: 1.数组结构:存储区间连续.内存占用严重.空间复杂度大 优点:因 ...
- ConcurrentHashMap的源码分析-transfer
扩容是ConcurrentHashMap的精华之一,扩容操作的核心在于数据的转移,在单线程环境下数据的转移很简单,无非就是把旧数组中的数据迁移到新的数组.但是这在多线程环境下,在扩容的时候其他线程也可 ...
- ConcurrentHashMap的源码分析-JDK1.7和Jdk1.8版本的变化
ConcurrentHashMap和HashMap的实现原理是差不多的,但是因为ConcurrentHashMap需要支持并发操作,所以在实现上要比hashmap稍微复杂一些. 在JDK1.7的实现上 ...
- ConcurrentHashMap的源码分析-高低位原理分析
ConcurrentHashMap在做链表迁移时,会用高低位来实现,这里有两个问题要分析一下 1. 如何实现高低位链表的区分 假如我们有这样一个队列 第14个槽位插入新节点之后,链表元素个数已经达到了 ...
- [集合]ConcurrentHashMap的源码分析
前言: 强推:一文读懂HashMap 这感觉讲的HashMap很明白. 1. 多线程环境下面,HashMap和Hashtable会怎么样? 1.1 HashMap 因为put会调用: // 新增Ent ...
- ConcurrentHashMap的源码分析-扩容过程图解
ConcurrentHashMap支持并发扩容,实现方式是,把Node数组进行拆分,让每个线程处理自己的区域,假设table数组总长度是64,默认情况下,那么每个线程可以分到16个bucket. 然后 ...
- ConcurrentHashMap的源码分析-resizeStamp
这块逻辑要理解起来,也有一点复杂. resizeStamp用来生成一个和扩容有关的扩容戳,具体有什么作用呢?我们基于它的实现来做一个分析 static final int resizeStamp(in ...
- ConcurrentHashMap的源码分析-CounterCells初始化图解
初始化长度为2的数组,然后随机得到指定的一个数组下标,将需要新增的值加入到对应下标位置处 transfer扩容阶段 判断是否需要扩容,也就是当更新后的键值对总数baseCount >= 阈值si ...
- ConcurrentHashMap的源码分析-CounterCells解释
ConcurrentHashMap是采用CounterCell数组来记录元素个数的,像一般的集合记录集合大小,直接定义一个size的成员变量即可,当出现改变的时候只要更新这个变量就行.为什么Concu ...
最新文章
- 孙正义真会玩,这个「人不是人,狗不是狗」的画面,价值上千万
- Linux存储入门:简易数据恢复方案--分区和LVM实战
- activiti流程跟踪图简单详解
- node-red教程 7dashboard简介与输入型仪表板控件的使用
- java清屏_【图片】请问java编写中如何做到清屏啊。。。_java吧_百度贴吧
- 清华MBZUAICMU牛津提出DenseCLIP,用上下文感知的提示进行语言引导密集预测!代码已开源!...
- glusterfs java_GlusterFS分布式文件系统使用简介
- 快手抢占短视频第一股,增长惊人,腾讯又是大赢家!
- Docker离线安装教程(Centos7) 转帖
- Android--Handler
- 初始runtime(运行时机制)
- 漫画:什么是A*寻路算法?
- 禅道 非内置mysql_禅道
- Android studio进行文件对比
- 人工智能与算法学习总结报告!(珍藏版)
- 智能投顾-用户画像、投资组合选择、推荐引擎、大数据挖掘
- Rockchip WIFI 配置说明
- Wish官方推荐收款渠道 哪家比较好?
- BIOS设置 硬盘热插拔功能
- 清理电脑C盘全攻略 - 是时候给你的系统盘放个假了!