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 源码相关推荐

  1. ConcurrentHashMap源码分析(2)——JDK1.8的实现

    ConcurrentHashMap源码分析(1)--JDK1.7的实现 前言 在JDK1.7版本上,ConcurrentHashMap还是通过分段锁来实现的,Segment的数量制约着并发量.在JDK ...

  2. ConcurrentHashMap源码分析(1)——JDK1.7的实现

    ConcurrentHashMap源码分析 ConcurrentHashMap源码分析(2)--JDK1.8的实现 前言 ConcurrentHashMap是线程安全且高效的HashMap的实现,在并 ...

  3. JDK8中ConcurrentHashMap源码解析

    在介绍ConcurrentHashMap源码之前,首先需要了解以下几个知识 1.JDK1.8中ConcurrentHashMap的基本结构 2.并发编程的三个概念:可见性,原子性,有序性 3.CAS( ...

  4. ConcurrentHashMap源码学习

    ConcurrentHashMap源码学习 自从学习了AQS之后,想着重新读一下ConcurrentHashMap的源码来加深下理解,所以有了这篇文章,针对ConcurrentHashMap常用的方法 ...

  5. ConcurrentHashMap源码剖析(1.8版本)

    目录 ConcurrentHashMap源码剖析 数据结构 Node ForwardingNode TreeNode TreeBin 核心成员 核心函数 ConcurrentHashMap(int i ...

  6. 面试官系统精讲Java源码及大厂真题 - 16 ConcurrentHashMap 源码解析和设计思路

    16 ConcurrentHashMap 源码解析和设计思路 与有肝胆人共事,从无字句处读书. 引导语 当我们碰到线程不安全场景下,需要使用 Map 的时候,我们第一个想到的 API 估计就是 Con ...

  7. JDK1.8 中 ConcurrentHashMap源码分析(一)容器初始化

    上一篇文章中说到如何使用IDEA搭建JDK1.8阅读学习环境,JDK1.8源码下载及获取.导入IDEA阅读.配置JDK源码.这篇文章将学习ConcurrentHashMap源码

  8. ConcurrentHashMap源码跟踪记录

    2019独角兽企业重金招聘Python工程师标准>>> concurrentHashMap源码解读 主要理解几个问题1 ConcurrentHashMap如何实现分段锁2 存取数据是 ...

  9. ConcurrentHashMap源码分析,轻取面试Offer(一)

    ConcurrentHashMap 这里主要分析的 jdk1.8中的ConcurrentHashMap,他是java之父Doug Lea之作,很多优秀的开源框架如tomcat.spring.中都大量用 ...

  10. ConcurrentHashMap源码分析,轻取面试Offer(二)

    上篇ConcurrentHashMap源码分析,轻取面试Offer(一)中降到了看源码的方法,下面接上篇继续分析源码 先来上篇注释过的代码段和遗留的问题. final V putVal(K key, ...

最新文章

  1. 【Chat】实验 -- 实现 C/C++下TCP, 服务器/客户端 多人聊天室
  2. R语言plotly可视化:plotly可视化分组归一化直方图(historgram)并在直方图中添加密度曲线kde、并在直方图的底部部边缘使用geom_rug函数添加边缘轴须图
  3. 软件测试自动化的成功经验
  4. n/2^n的前n项和,Sn=∑n/2^n
  5. 【sql】leetcode习题 (共 42 题)
  6. 日常问题——使用Xshell 连接虚拟机报错 Disconnected from remote host
  7. Tensorflow中使用tfrecord,队列方式读取数据
  8. @sql 单元测试_如何在SQL单元测试中使用假表?
  9. LeetCode for SQL 176. 第二高的薪水 (ifnull limit order by)
  10. hdu 5402 Travelling Salesman Problem (技巧,未写完)
  11. zen brush 2 android,Zen Brush 2 才不仅仅是个练字 App 那么简单
  12. Struts2框架中为什么要继承ActionSupport类,以及实现过程
  13. RDCMan 安装问题
  14. 下行物理信道rs_LTE下行物理信道与物理信号
  15. acdsee怎么改图片大小|acdsee怎么用
  16. JQ与JS实现全选按钮案例
  17. 人应该怎样度过自己的一生
  18. 求大神帮助 百练我爱北大,编程题目
  19. Webx系列之文件下载
  20. 【STL】C++ STL超全总结

热门文章

  1. 网络游戏中网络模块浅析
  2. 飞鸽传书(http://www.freeeim.com)软件下载
  3. 在 Visual C++ 中使用内联汇编
  4. 程序员都很老实?你错了,其实程序员真实的样子是这样的
  5. 我发誓:下辈子再也不学JavaScript了
  6. cgi mysql数据库_Perl CGI中操作Mysql数据库
  7. html5 字母索引,jQuery建立一个按字母顺序排列的友好页面索引(兼容IE6/7/8)
  8. 鸿蒙os开发者大会的时间,华为开发者大会2020时间已确定,鸿蒙2.0和EMUI 11即将到来...
  9. 易生信极高性价比暑期黑马集训 -- 低至2500每人
  10. Linux学习 - sed使用