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

问题还是处在并发上,ConcurrentHashMap是并发集合,如果用一个成员变量来统计元素个数的话,为了保证并发情况下共享变量的的难全兴,势必会需要通过加锁或者自旋来实现,如果竞争比较激烈的情况下,size的设置上会出现比较大的冲突反而影响了性能,所以在ConcurrentHashMap采用了分片的方法来记录大小,具体什么意思,我们来分析下

private transient volatile int cellsBusy;// 标识当前cell数组是否在初始化或扩容中的CAS标志位
/**
* Table of counter cells. When non-null, size is a power of 2.
*/
private transient volatile CounterCell[] counterCells;// counterCells数组,总数值的分值分别存在每个cell中 @sun.misc.Contended static final class CounterCell { volatile long value; CounterCell(long x) { value = x; }
}
//看到这段代码就能够明白了,CounterCell数组的每个元素,都存储一个元素个数,而实际我们调用size方法就是通过这个循环累加来得到的 //又是一个设计精华,大家可以借鉴; 有了这个前提,再会过去看addCount这个方法,就容易理解一些了
final long sumCount() { CounterCell[] as = counterCells; CounterCell a; long sum = baseCount; if (as != null) { for (int i = 0; i < as.length; ++i) { if ((a = as[i]) != null) sum += a.value; } } return sum;
}

ConcurrentHashMap的源码分析-CounterCells解释相关推荐

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

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

  2. HashMap与ConcurrentHashMap万字源码分析

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

  3. ConcurrentHashMap的源码分析-transfer

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

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

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

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

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

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

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

  7. ConcurrentHashMap的源码分析-addCount

    在putVal最后调用addCount的时候,传递了两个参数,分别是1和binCount(链表长度),看看addCount方法里面做了什么操作 x表示这次需要在表中增加的元素个数,check参数表示是 ...

  8. ConcurrentHashMap的源码分析-为什么要做高低位的划分

    要想了解这么设计的目的,我们需要从ConcurrentHashMap的根据下标获取对象的算法来看,在putVal方法中1018行 (f = tabAt(tab, i = (n - 1) & h ...

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

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

最新文章

  1. 【项目经理应该知道的97件事】三位一体的项目管理
  2. linux配置4g网络命令_Linux网络基本配置命令
  3. 兼容浏览器_你知道什么是跨浏览器兼容吗?
  4. linux 文件批量转utf8
  5. swoole-co-pool v1.0.1,Swoole 协程工作池
  6. Qt多线程学习:创建多线程
  7. 互联网1分钟 |1205
  8. java stop graceful
  9. 模板载入与模板继承的区别
  10. TensorFlow学习笔记(五)Session的2种用法
  11. 线段树-Mex-洛谷P4137
  12. shell逻辑判断和-a区别
  13. 高级GIS-0.整体裁剪
  14. 阿里矢量图标(字体图标) 、 阴影
  15. linux下的rpm命令详解,RPM包命令详解
  16. 店宝宝:电视剧“拼刀刀”梗引热议 拼多多紧急注册商标为哪版?
  17. 免费企业邮箱: Google企业邮箱的申请
  18. 杀死一只知更鸟——派克的经典作品
  19. Android控件之Button
  20. java关闭端口_使用java代码关闭指定端口的程序-windows

热门文章

  1. ASP.NET2.0中配置文件的加密与解密
  2. 文本分类-TensorRT优化结果对比图
  3. TP框架对数据库的基本操作
  4. 生成器模式 - 让配置代码更优雅
  5. 什么是REST?以及RESTful的实现(转)
  6. javascript,jquery 操作 dropdownlist ,select
  7. Linux下部署MyEclipse开发环境
  8. webpack之proxyTable配置
  9. Flutter探索与实践
  10. 轻松搞定对容器实例日志设置定期清理和回卷