ConcurrentHashMap源码
----------------------------------------------------------------------------------------------------------
TheadLocalRandom初始化是把当前线程自己的的种子threadLocalRandomSeed和随机数threadLocalRandomProbe两个属性设置了,getProbe方法其实是用unsafe取当前线程对象中取出随机数的值
-------------------------------------------------------------------------------------------------------
进入fullAddCount方法就意味着并发量很高,cas修改baseCount出现失败的情况了,需要往辅助的储存格里暂存。其实CounterCells就是一个根据并发压力不断2-4-8-16这样扩容的一个数组。不同线程根据随机数hash之后有可能使用同一个格子,所以要有一个全局锁cellsbusy,避免初始化格子数组或者当前格子的时候,并发冲突。ThreadLocalRandom.advanceProbe,同一个格子位并发太高还可以重新生成随机数。
---------------------------------------------------------------------------------------------------------
helpTransfer的核心方法是transfer,在调用之前先做判断(别处调用transfer之前都一样):
一:如果sizeCtl为负,说明此时已经有线程已经开始transfer,那么把当前的sizeCtl+1,这个和ReentrantLock的共享锁是一样的。
二,如果不为负,说明当前线程是第一个开始扩容的,会resizeStamp一下,得到一个保存有tablelength信息的负数(为什么要+2)再替换sizeCtl。
关于sizeCtl:
在transfer中,while(advance)中会判断,如果交替扩容使得transferIndex<=0,说明所有的按stride长度分割的所有区域都已经有线程或正在扩容或已扩容完毕
那么先把自己当前线程的i设置为-1,就可以进入将sizeCtl减一的操作,使得当前线程结束扩容,当前线程退出扩容前,要先通过 sizeCtl减完自己的1之后是否是之前说的resizeStamp右移再加2,.
如果是,说明其他线程都扩容完毕,自己是最后一个线程,那么把newTable属性设置为null,当前table指向newTable,sizeCtl变为新table长度的0.75倍。如果不是,说明还有别的线程在扩容,那么直接返回。
--------------------------------------------------------------------------------------------------------------
stride是并发扩容分区的跨度,table长度不是太大的话一直是16,很大的话会相应扩大。第一个线程A从table最底端开始扩容,下一个线程B(B有可能是A)跨度到tableLength-stride*1的位置开始扩容,下一个线程C跨度到tableLength-stride*2的位置开始扩容。
判断扩容线程数的逻辑在上面,判断从哪个位置开始扩容是在while(advance)中,借助transferIndex 这个变量。分段扩容可以避免并发冲突(冲突发生在比如每次tabAt==null之后的cas为fwdNode,和tabAt!=null的synchronized)
扩容的时候,旧table的链表(或者红黑树)在新table中,被重新hash之后分成两个链表,如果其中有链表长度大于转成红黑树阈值,那么在赋值给新table对应槽位的时候,在红黑树化。换句话说,也就是旧table有旧的链表指向所有的k,v。新链表也有新的两条链表分
别指向原来的k,v。这就是为什么扩容的同时查找并不会受链表一分为二影响。
------------------------------------------------------------------------------------------------------------------
put remove 略
ConcurrentHashMap源码的更多相关文章
- JDK1.7 ConcurrentHashMap 源码浅析
概述 ConcurrentHashMap是HashMap的线程安全版本,使用了分段加锁的方案,在高并发时有比较好的性能. 本文分析JDK1.7中ConcurrentHashMap的实现. 正文 Con ...
- Hashtable、ConcurrentHashMap源码分析
Hashtable.ConcurrentHashMap源码分析 为什么把这两个数据结构对比分析呢,相信大家都明白.首先二者都是线程安全的,但是二者保证线程安全的方式却是不同的.废话不多说了,从源码的角 ...
- ConcurrentHashMap源码分析(一)
本篇博客的目录: 前言 一:ConcurrentHashMap简介 二:ConcurrentHashMap的内部实现 三:总结 前言:HashMap很多人都熟悉吧,它是我们平时编程中高频率出现的一种集 ...
- ConcurrentHashMap 源码分析
ConcurrentHashMap 源码分析 1. 前言 终于到这个类了,其实在前面很过很多次这个类,因为这个类代码量比较大,并且涉及到并发的问题,还有一点就是这个代码有些真的晦涩,不好懂.前前 ...
- 死磕 java集合之ConcurrentHashMap源码分析(三)
本章接着上两章,链接直达: 死磕 java集合之ConcurrentHashMap源码分析(一) 死磕 java集合之ConcurrentHashMap源码分析(二) 删除元素 删除元素跟添加元素一样 ...
- JDK12 concurrenthashmap源码阅读
本文部分照片和代码分析来自文末参考资料 java8中的concurrenthashmap的方法逻辑和注解有些问题,建议看最新的JDK版本 建议阅读 concu ...
- 并发-ConcurrentHashMap源码分析
ConcurrentHashMap 参考: http://www.cnblogs.com/chengxiao/p/6842045.html https://my.oschina.net/hosee/b ...
- 数据结构算法 - ConcurrentHashMap 源码解析
五个线程同时往 HashMap 中 put 数据会发生什么? ConcurrentHashMap 是怎么保证线程安全的? 在分析 HashMap 源码时还遗留这两个问题,这次我们站在 Java 多线程 ...
- ConcurrentHashMap源码走读
目录 ConcurrentHashMap源码走读 简介 放入数据 容器元素总数更新 容器扩容 协助扩容 遍历 ConcurrentHashMap源码走读 简介 在从JDK8开始,为了提高并发度,Con ...
- JDK8中的ConcurrentHashMap源码
背景 上文JDK8中的HashMap源码写了HashMap,这次写ConcurrentHashMap ConcurrentHashMap源码 /** * Maps the specified key ...
随机推荐
- 全景拍摄,全景视频拍摄,全景VR拍摄,VR全景拍摄,360全景图片拍摄
北京动软专业提供基于手机.VR设备.PC浏览器的全景拍摄和项目展示服务. 承接服务内容包括720°全景拍摄展示.VR虚拟现实全景.全景漫游.全景视频.物体全景.环物全景等. 全景展示主要应用于展览 ...
- 使用RStudio调试(debug)基础学习(二)和fGarch包中的garchFit函数估计GARCH模型的原理和源码
一.garchFit函数的参数--------------------------------------------- algorithm a string parameter that deter ...
- Crashing Robots(水题,模拟)
1020: Crashing Robots 时间限制(普通/Java):1000MS/10000MS 内存限制:65536KByte 总提交: 207 测试通过:101 ...
- 用 jupyter notebook 打开 oui.txt 文件出现的问题及解决方案
问题背景:下载了2018 IEEE 最新的 oui.txt 文件.里面包含了 设备 MAC 地址的前六位对应的厂商.要做的工作是,将海量设备的 MAC 地址与 oui.txt 文件的信息比对,统计出 ...
- 分页查询最好加排序(order by)
昨天,与外部化系统对接时,发现有一个数据一直咩有集成到,双方各自排查了自己系统的代码,都觉得逻辑非常简单,无法就是一个分页查询而已. 问题就出在这个分页查询上. 为了说明当时问题发生的情景,我模拟了一 ...
- 记录一下小程序canvas
小程序canvas学习 效果图: .wxml <canvas style="width: 100vw; height: 100vh;" canvas-id="fir ...
- Vue-CLI3.0版本配置BootStrap的方法
一.引入jquery bootstrap popper 用 cnpm install jquery bootstrap@3 popper.js --save 用cnpm 来导入 用npm会出 ...
- java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context 错误
spring boot 项目启动报错:原因一般是注入了相同名字的service -- :: com.gxcards.mes.MainWwwWeb: logStartupProfileInfo INFO ...
- Headless Service 和Service
定于spec:clusterIP: None 还记得Service的Cluster IP是做什么的吗?对,一个Service可能对应多个EndPoint(Pod),client访问的是Cluster ...
- Pycharm 中You are using pip version 10.0.1, however version 18.1 is available. You should consider upgrading via the 'python -m pip install --upgrade pip' command.
今天运行程序的时候出现了: You are using pip version 10.0.1, however version 18.1 is available.You should conside ...