在putVal最后调用addCount的时候,传递了两个参数,分别是1和binCount(链表长度),看看addCount方法里面做了什么操作

x表示这次需要在表中增加的元素个数,check参数表示是否需要进行扩容检查,大于等于0都需要进行检查

private final void addCount(long x, int check) { CounterCell[] as; long b, s;判断counterCells是否为空,1. 如果为空,就通过cas操作尝试修改baseCount变量,对这个变量进行原子累加操作(做这个操作的意义是:如果在没有竞争的情况下,仍然采用baseCount来记录元素个数) 2. 如果cas失败说明存在竞争,这个时候不能再采用baseCount来累加,而是通过CounterCell来记录if ((as = counterCells) != null || !U.compareAndSwapLong(this, BASECOUNT, b = baseCount, s = b + x)){ CounterCell a; long v; int m; boolean uncontended = true;//是否冲突标识,默认为没有冲突 这里有几个判断 1. 计数表为空则直接调用fullAddCount 2. 从计数表中随机取出一个数组的位置为空,直接调用fullAddCount 3. 通过CAS修改CounterCell随机位置的值,如果修改失败说明出现并发情况(这里又用到了一种巧妙的方法),调用fullAndCount Random在线程并发的时候会有性能问题以及可能会产生相同的随机数,ThreadLocalRandom.getProbe可以解决这个问题,并且性能要比Random高 if (as == null || (m = as.length - 1) < 0 || (a = as[ThreadLocalRandom.getProbe() & m]) == null || !(uncontended = U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))) { fullAddCount(x, uncontended);//执行fullAddCount方法 return; } if (check <= 1)//链表长度小于等于1,不需要考虑扩容 return; s = sumCount();//统计ConcurrentHashMap元素个数 } //….
} 

ConcurrentHashMap的源码分析-addCount相关推荐

  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的源码分析

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

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

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

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

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

  7. ConcurrentHashMap的源码分析-put方法第二阶段

    在putVal方法执行完成以后,会通过addCount来增加ConcurrentHashMap中的元素个数,并且还会可能触发扩容操作.这里会有两个非常经典的设计 1. 高并发下的扩容 2. 如何保证a ...

  8. ConcurrentHashMap的源码分析-tryPresize

    tryPresize里面部分代码和addCount的部分代码类似,看起来会稍微简单一些 private final void tryPresize(int size) {//对size进行修复,主要目 ...

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

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

最新文章

  1. abb机器人指令手册_ABB机器人编程之程序流程指令(含案例)
  2. 肖婧医生直播讲稿整理
  3. flutter中的异步机制Future
  4. Toolkit.getDefaultToolkit().getScreenSize();获取显示器屏幕大小并使JFrame窗口居中显示
  5. ios上input框上边有阴影
  6. (23)VHDL实现乘法器
  7. 白板推导系列Pytorch实现-感知机算法
  8. 超维android10框架什么功能,基于Android系统深度定制,努比亚阿尔法搭载α OS带来新交互...
  9. 在线latex 网址
  10. 软件测试能干到多少岁,老了怎么办?
  11. WIN7封装教程2018系列(六)—封装
  12. 【LeetCode】954. Array of Doubled Pairs 解题报告(Python)
  13. 电商浪潮过后,无人零售会引领新零售的爆发吗
  14. 动态排程才是生产计划排程的根本
  15. python通过qq邮箱发邮件
  16. Java工程师的工资待遇如何?
  17. 7-17 爬动的蠕虫
  18. 地图数据赋能ADAS的探索与实践(转载)
  19. 多维数据格式mdd结构与计算机配套系统,多维数据分析系统
  20. 惠普实习笔记(一):入门servlet

热门文章

  1. 英文名字大全(男篇)
  2. 第二单元作业——电梯模拟总结
  3. selenium自动加载Flash
  4. python框架Flask学习笔记之get和post请求
  5. Android源代码解析之(四)--gt;HandlerThread
  6. 论一只爬虫的自我修养
  7. WPF整理-处理没有注意到的异常
  8. python中的property
  9. 【研究任务】linux系统开机启动过程
  10. linux 下实现ssh免密钥登录