ConcurrentHashMap 源码
1.7 构造函数
// 16 0.75 16public ConcurrentHashMap(int initialCapacity,float loadFactor, int concurrencyLevel) {if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0)throw new IllegalArgumentException();if (concurrencyLevel > MAX_SEGMENTS) //1 << 16 65536concurrencyLevel = MAX_SEGMENTS;// Find power-of-two sizes best matching arguments//找到最接近的2的幂次方数int sshift = 0;int ssize = 1;//segment数组的长度while (ssize < concurrencyLevel) {++sshift; // 1 2 3 [4] 5 取hash的高四位,put时候用高4(sshift)位求segment数组的index值,低4位用于求hashtable[]的index值ssize <<= 1;//左移 2 4 8 [16] 32}this.segmentShift = 32 - sshift; //28this.segmentMask = ssize - 1;// 16 -1(0000 1111) 用来取table index = hash & (ssize -1)if (initialCapacity > MAXIMUM_CAPACITY)//1 << 30 1073741824initialCapacity = MAXIMUM_CAPACITY;int c = initialCapacity / ssize; // 16/16 = 1 每个segment里面的hashEntry数组的数量if (c * ssize < initialCapacity) //initialCapacity=16 初始参数 保证总hashEntry数量大于初始化得数量++c;int cap = MIN_SEGMENT_TABLE_CAPACITY; // MIN_SEGMENT_TABLE_CAPACITY = 2while (cap < c)cap <<= 1;//左移 2的幂次数 hashEntry[]数组的长度也要是2的幂次方// create segments and segments[0]Segment<K,V> s0 =new Segment<K,V>(loadFactor, (int)(cap * loadFactor),(HashEntry<K,V>[])new HashEntry[cap]);Segment<K,V>[] ss = (Segment<K,V>[])new Segment[ssize];UNSAFE.putOrderedObject(ss, SBASE, s0); // ordered write of segments[0]//Unsafe CAS技术this.segments = ss;}
1.7 ConcurrentHashmap.put()
@SuppressWarnings("unchecked")public V put(K key, V value) {Segment<K,V> s;if (value == null)throw new NullPointerException();int hash = hash(key);//segmentShift默认值是32 -4 =28,int值一共32位 所以取hash值的高四位int j = (hash >>> segmentShift) & segmentMask;//使用hash值的高4位 &segmentMask是segment长度减1if ((s = (Segment<K,V>)UNSAFE.getObject // Unsafe检查segment时候存在(segments, (j << SSHIFT) + SBASE)) == null) // in ensureSegments = ensureSegment(j); //新建并使用CAS插入segmentreturn s.put(key, hash, value, false);//将键值对插入Segment}
Segment.put()
Segment.putfinal V put(K key, int hash, V value, boolean onlyIfAbsent) {HashEntry<K,V> node = tryLock() ? null :scanAndLockForPut(key, hash, value);V oldValue;try {HashEntry<K,V>[] tab = table;int index = (tab.length - 1) & hash;HashEntry<K,V> first = entryAt(tab, index);//获取第一个节点for (HashEntry<K,V> e = first;;) {//遍历链表if (e != null) {K k;if ((k = e.key) == key ||(e.hash == hash && key.equals(k))) {//找到key相等的HashEntry 并替换value值oldValue = e.value;if (!onlyIfAbsent) {e.value = value;++modCount;}break;}e = e.next;}//到达最后一个节点else {if (node != null)node.setNext(first);elsenode = new HashEntry<K,V>(hash, key, value, first);//创建新节点int c = count + 1;if (c > threshold && tab.length < MAXIMUM_CAPACITY)rehash(node);//扩容这个Segment的hashEntry[]数组elsesetEntryAt(tab, index, node);++modCount;count = c;oldValue = null;break;}}} finally {unlock();}return oldValue;}
ConcurrentHashMap 源码相关推荐
- ConcurrentHashMap源码分析(2)——JDK1.8的实现
ConcurrentHashMap源码分析(1)--JDK1.7的实现 前言 在JDK1.7版本上,ConcurrentHashMap还是通过分段锁来实现的,Segment的数量制约着并发量.在JDK ...
- ConcurrentHashMap源码分析(1)——JDK1.7的实现
ConcurrentHashMap源码分析 ConcurrentHashMap源码分析(2)--JDK1.8的实现 前言 ConcurrentHashMap是线程安全且高效的HashMap的实现,在并 ...
- JDK8中ConcurrentHashMap源码解析
在介绍ConcurrentHashMap源码之前,首先需要了解以下几个知识 1.JDK1.8中ConcurrentHashMap的基本结构 2.并发编程的三个概念:可见性,原子性,有序性 3.CAS( ...
- ConcurrentHashMap源码学习
ConcurrentHashMap源码学习 自从学习了AQS之后,想着重新读一下ConcurrentHashMap的源码来加深下理解,所以有了这篇文章,针对ConcurrentHashMap常用的方法 ...
- ConcurrentHashMap源码剖析(1.8版本)
目录 ConcurrentHashMap源码剖析 数据结构 Node ForwardingNode TreeNode TreeBin 核心成员 核心函数 ConcurrentHashMap(int i ...
- 面试官系统精讲Java源码及大厂真题 - 16 ConcurrentHashMap 源码解析和设计思路
16 ConcurrentHashMap 源码解析和设计思路 与有肝胆人共事,从无字句处读书. 引导语 当我们碰到线程不安全场景下,需要使用 Map 的时候,我们第一个想到的 API 估计就是 Con ...
- JDK1.8 中 ConcurrentHashMap源码分析(一)容器初始化
上一篇文章中说到如何使用IDEA搭建JDK1.8阅读学习环境,JDK1.8源码下载及获取.导入IDEA阅读.配置JDK源码.这篇文章将学习ConcurrentHashMap源码
- ConcurrentHashMap源码跟踪记录
2019独角兽企业重金招聘Python工程师标准>>> concurrentHashMap源码解读 主要理解几个问题1 ConcurrentHashMap如何实现分段锁2 存取数据是 ...
- ConcurrentHashMap源码分析,轻取面试Offer(一)
ConcurrentHashMap 这里主要分析的 jdk1.8中的ConcurrentHashMap,他是java之父Doug Lea之作,很多优秀的开源框架如tomcat.spring.中都大量用 ...
- ConcurrentHashMap源码分析,轻取面试Offer(二)
上篇ConcurrentHashMap源码分析,轻取面试Offer(一)中降到了看源码的方法,下面接上篇继续分析源码 先来上篇注释过的代码段和遗留的问题. final V putVal(K key, ...
最新文章
- 【Chat】实验 -- 实现 C/C++下TCP, 服务器/客户端 多人聊天室
- R语言plotly可视化:plotly可视化分组归一化直方图(historgram)并在直方图中添加密度曲线kde、并在直方图的底部部边缘使用geom_rug函数添加边缘轴须图
- 软件测试自动化的成功经验
- n/2^n的前n项和,Sn=∑n/2^n
- 【sql】leetcode习题 (共 42 题)
- 日常问题——使用Xshell 连接虚拟机报错 Disconnected from remote host
- Tensorflow中使用tfrecord,队列方式读取数据
- @sql 单元测试_如何在SQL单元测试中使用假表?
- LeetCode for SQL 176. 第二高的薪水 (ifnull limit order by)
- hdu 5402 Travelling Salesman Problem (技巧,未写完)
- zen brush 2 android,Zen Brush 2 才不仅仅是个练字 App 那么简单
- Struts2框架中为什么要继承ActionSupport类,以及实现过程
- RDCMan 安装问题
- 下行物理信道rs_LTE下行物理信道与物理信号
- acdsee怎么改图片大小|acdsee怎么用
- JQ与JS实现全选按钮案例
- 人应该怎样度过自己的一生
- 求大神帮助 百练我爱北大,编程题目
- Webx系列之文件下载
- 【STL】C++ STL超全总结
热门文章
- 网络游戏中网络模块浅析
- 飞鸽传书(http://www.freeeim.com)软件下载
- 在 Visual C++ 中使用内联汇编
- 程序员都很老实?你错了,其实程序员真实的样子是这样的
- 我发誓:下辈子再也不学JavaScript了
- cgi mysql数据库_Perl CGI中操作Mysql数据库
- html5 字母索引,jQuery建立一个按字母顺序排列的友好页面索引(兼容IE6/7/8)
- 鸿蒙os开发者大会的时间,华为开发者大会2020时间已确定,鸿蒙2.0和EMUI 11即将到来...
- 易生信极高性价比暑期黑马集训 -- 低至2500每人
- Linux学习 - sed使用