要想了解这么设计的目的,我们需要从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的源码分析-为什么要做高低位的划分相关推荐

  1. HashMap与ConcurrentHashMap万字源码分析

    HashMap与ConcurrentHashMap`源码解析 JDK版本:1.7 & 1.8 ​ 开发中常见的数据结构有三种: 1.数组结构:存储区间连续.内存占用严重.空间复杂度大 优点:因 ...

  2. ConcurrentHashMap的源码分析-transfer

    扩容是ConcurrentHashMap的精华之一,扩容操作的核心在于数据的转移,在单线程环境下数据的转移很简单,无非就是把旧数组中的数据迁移到新的数组.但是这在多线程环境下,在扩容的时候其他线程也可 ...

  3. ConcurrentHashMap的源码分析-JDK1.7和Jdk1.8版本的变化

    ConcurrentHashMap和HashMap的实现原理是差不多的,但是因为ConcurrentHashMap需要支持并发操作,所以在实现上要比hashmap稍微复杂一些. 在JDK1.7的实现上 ...

  4. ConcurrentHashMap的源码分析-高低位原理分析

    ConcurrentHashMap在做链表迁移时,会用高低位来实现,这里有两个问题要分析一下 1. 如何实现高低位链表的区分 假如我们有这样一个队列 第14个槽位插入新节点之后,链表元素个数已经达到了 ...

  5. [集合]ConcurrentHashMap的源码分析

    前言: 强推:一文读懂HashMap 这感觉讲的HashMap很明白. 1. 多线程环境下面,HashMap和Hashtable会怎么样? 1.1 HashMap 因为put会调用: // 新增Ent ...

  6. ConcurrentHashMap的源码分析-扩容过程图解

    ConcurrentHashMap支持并发扩容,实现方式是,把Node数组进行拆分,让每个线程处理自己的区域,假设table数组总长度是64,默认情况下,那么每个线程可以分到16个bucket. 然后 ...

  7. ConcurrentHashMap的源码分析-resizeStamp

    这块逻辑要理解起来,也有一点复杂. resizeStamp用来生成一个和扩容有关的扩容戳,具体有什么作用呢?我们基于它的实现来做一个分析 static final int resizeStamp(in ...

  8. ConcurrentHashMap的源码分析-CounterCells初始化图解

    初始化长度为2的数组,然后随机得到指定的一个数组下标,将需要新增的值加入到对应下标位置处 transfer扩容阶段 判断是否需要扩容,也就是当更新后的键值对总数baseCount >= 阈值si ...

  9. ConcurrentHashMap的源码分析-CounterCells解释

    ConcurrentHashMap是采用CounterCell数组来记录元素个数的,像一般的集合记录集合大小,直接定义一个size的成员变量即可,当出现改变的时候只要更新这个变量就行.为什么Concu ...

最新文章

  1. 孙正义真会玩,这个「人不是人,狗不是狗」的画面,价值上千万
  2. Linux存储入门:简易数据恢复方案--分区和LVM实战
  3. activiti流程跟踪图简单详解
  4. node-red教程 7dashboard简介与输入型仪表板控件的使用
  5. java清屏_【图片】请问java编写中如何做到清屏啊。。。_java吧_百度贴吧
  6. 清华MBZUAICMU牛津提出DenseCLIP,用上下文感知的提示进行语言引导密集预测!代码已开源!...
  7. glusterfs java_GlusterFS分布式文件系统使用简介
  8. 快手抢占短视频第一股,增长惊人,腾讯又是大赢家!
  9. Docker离线安装教程(Centos7) 转帖
  10. Android--Handler
  11. 初始runtime(运行时机制)
  12. 漫画:什么是A*寻路算法?
  13. 禅道 非内置mysql_禅道
  14. Android studio进行文件对比
  15. 人工智能与算法学习总结报告!(珍藏版)
  16. 智能投顾-用户画像、投资组合选择、推荐引擎、大数据挖掘
  17. Rockchip WIFI 配置说明
  18. Wish官方推荐收款渠道 哪家比较好?
  19. BIOS设置 硬盘热插拔功能
  20. 清理电脑C盘全攻略 - 是时候给你的系统盘放个假了!

热门文章

  1. 女生适不适学习Java编程
  2. idea git 发起一个pull request 请求
  3. 在mac上搭建了Java 环境,谨以此文写给自己
  4. 【书单】matlab 科学计算、数值分析以及数学物理问题
  5. spring-cloud 学习三 服务提供者
  6. fastweixin v1.3.0 发布,极速微信公众号开发框架
  7. SQL Server中截取字符串常用函数
  8. Visual Studio 2008 响应很慢 是怎么回事?
  9. 设计模式笔记(19)---观察者模式(行为型)
  10. sql语句转化为分页查询的一种实现