参考:https://www.jianshu.com/p/c0642afe03e0

CAS的思想很简单:三个参数,一个当前内存值V、旧的预期值A、即将更新的值B,当且仅当预期值A和内存值V相同时,将内存值修改为B并返回true,否则什么都不做,并返回false。

细节参考:https://www.jianshu.com/p/fb6e91b013cc

参考:http://blog.csdn.net/u010412719/article/details/52145145

   https://www.jianshu.com/p/c0642afe03e0

总结:CAS操作就是将内存中的值和预期中的值比较,相等则修改,并返回true,不相等返回false
casTabAt(Node<K,V>[] tab, int i, Node<K,V> c, Node<K,V> v) (将c与tab[i]比较)设置节点上的值
相对于synchronized操作要更快。

concurrenthashmap在jdk中1.8中利用CAS+Synchronized来保证并发更新的安全,没有利用segment分段锁的机制。
concurrentHashMap扩容
1、put新增一个节点,计算hash值。
检验entry数据是否初始化?没有,那么初始化initTable
检验table[i]是否为null?为null,利用cas添加节点
不为null,判断是否在扩容?在扩容帮助扩容,没有则helpTransfer帮助扩容
以上情况均不符合,synchronized锁定头节点,判断为链表节点,则插入链表的尾部
判断为树节点,则按照树添加节点
如果元素>=8?转化为树{
如果数组<64,扩容,只有当sizeCtl>0,才能扩容trasfer方法
如果数组>64,转化为树
}

2、扩容

情况1:当元素新增字节后,链表个数到达8,就会调用treeifBin把链表转化为
红黑树。在转化之前,如果数组长度小于阈值MIN_TREEIFY_CAPACITY,默认是64,
就会调用treePresize方法将数组扩大到原来的两倍。触发transfer方法,调整节点
的位置。
情况2:新增节点后,调用addCount方法记录元素个数,当达到阈值时就会调用transfer扩容

如果槽点为链表,由于是扩大到原来的两倍,transfer中就会利用fn&n快速将链表中的元素分为两类,分别生成一个和最后一节点fn&n相同的顺序列表,一个和最后一节点fn&n不同的反序列表,通过CAS把两者存储在新的数组中。

如果槽位为红黑树,则构造两个树节点,遍历红黑树,同样根据hash&n把节点分为两类,插入两个树节点的链表中。如果链表小于等于UNTREEIFY_THRESHOLD(6),则转化为普通列表。如果另一个节点的长度为0,那么将原始红黑树取过来。不然就根据链表重新创建树。最后通过CAS存储到新的数组中。

3、get
1、判断table是否为空,为空直接返回null
2、计算keyhash值,通过tabAt获得制定点的node,然后遍历链表或者树结构找到对应的点返回value

4、size
通过mappingCount获取size,主要时利用long替代int
但是两者计算出来都是一个估值,并没有像jdk1.7那样不断循环计算准确值

setTabAt(Node<K,V>[] tab, int i, Node<K,V> v){
//设置obj对象中offset偏移地址对应的object型field的值为指定值
U.putObjectVolatile(tab, ((long)i << ASHIFT) + ABASE, v);
}上锁时,设置节点上的值

tabAt(Node<K,V>[] tab, int i) 获取索引处node,保证读到最新对象

concurrenthashmap jdk1.8的更多相关文章

  1. ConcurrentHashMap(JDK1.8)为什么要放弃Segment

    今天看到一篇博客:jdk1.8的HashMap和ConcurrentHashMap,我想起了前段时间面试的一个问题:ConcurrentHashMap(JDK1.8)为什么要使用synchronize ...

  2. Java泛型底层源码解析--ConcurrentHashMap(JDK1.7)

    1. Concurrent相关历史 JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步容器将所有对容器状态的访问都串行化了,这样保证了线程的安全 ...

  3. 多线程-ConcurrentHashMap(JDK1.8)

    前言 HashMap非线程安全的,HashTable是线程安全的,所有涉及到多线程操作的都加上了synchronized关键字来锁住整个table,这就意味着所有的线程都在竞争一把锁,在多线程的环境下 ...

  4. 6.ConcurrentHashMap jdk1.7

    6.1 hash算法 就是把任意长度的输入,通过散列算法,变换成固定长度的输出,该输出就是散列值.这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所 ...

  5. Java并发编程总结4——ConcurrentHashMap在jdk1.8中的改进(转)

    一.简单回顾ConcurrentHashMap在jdk1.7中的设计 先简单看下ConcurrentHashMap类在jdk1.7中的设计,其基本结构如图所示: 每一个segment都是一个HashE ...

  6. Java并发编程总结4——ConcurrentHashMap在jdk1.8中的改进

    一.简单回顾ConcurrentHashMap在jdk1.7中的设计 先简单看下ConcurrentHashMap类在jdk1.7中的设计,其基本结构如图所示: 每一个segment都是一个HashE ...

  7. ConcurrentHashMap原理分析(1.7与1.8)

    前言 以前写过介绍HashMap的文章,文中提到过HashMap在put的时候,插入的元素超过了容量(由负载因子决定)的范围就会触发扩容操作,就是rehash,这个会重新将原数组的内容重新hash到新 ...

  8. 并发容器和框架之ConcurrentHashMap

    了解HashMap的人都知道HashMap是线程不安全的(多线程下的put方法达到一定大小,引发rehash,导致闭链,最终占满CPU),同时线程安全的HashTable效率又令人望而却步(每个方法都 ...

  9. 深入解析ConcurrentHashMap类

    以前写过介绍HashMap的文章,文中提到过HashMap在put的时候,插入的元素超过了容量(由负载因子决定)的范围就会触发扩容操作,就是rehash,这个会重新将原数组的内容重新hash到新的扩容 ...

随机推荐

  1. HTTP报文中的100状态码

    HTTP状态码(status codes)是HTTP协议中,响应报文的起始行中包含的一种服务器用于向客户端说明操作状态的三位数字.例如在一个正常的GET请求完成后,服务器会向客户端返回 HTTP/ O ...

  2. linux 网络编程 3---(io多路复用,tcp并发)

    1,io模型: 阻塞io.非阻塞io.io多路复用,信号驱动io. 阻塞Io与非阻塞io的转换,可用fcntl()函数 #include<unistd.h> #include<fcn ...

  3. VMWare虚拟机的网络类型配置选择详解

    VMWare虚拟机网络有三种类型,当然还有最后一种类型就是“不使用网络连接”,哈哈....... VMWare在安装会有让选择网络类型的选项,如果不确认使用那一种网络类型,也可以先随便选择一种网络类型 ...

  4. JavaScript---复选框反选全选

    Script <script type="text/javascript"> /*直接使用document.getElementsByName("c1&quo ...

  5. GDAL2.1.1库在Ubuntu14.04下编译时遇到的问题处理方法

    不用作任何调整,直接在Linux下编译GDAL2.1.1源码的步骤是: $ ./configure $ make $ make install 非常简单,这样也能正常生成gdal动态库.静态库,如果想 ...

  6. 为啥学蛇和python10年后的变化

    作者:cheng rianley链接:https://www.zhihu.com/question/22112542/answer/166053516来源:知乎著作权归作者所有.商业转载请联系作者获得 ...

  7. ORB-SLAM(六)MapPoint与Map

    地图点可以通过关键帧来构造,也可以通过普通帧构造,但是最终,必须是和关键帧对应的,通过普通帧构造的地图点只是临时被Tracking用来追踪用的. 构造函数(地图点3D坐标及其参考帧): // 参考帧是 ...

  8. PS 给天空添加蓝天白云<转载>

    https://jingyan.baidu.com/article/b2c186c8e83b1cc46ef6ffee.html 给图片添加蓝天白云的步骤: 1.打开要加蓝天白云的照片.(如图一) [图 ...

  9. 「日常训练」Bad Luck Island(Codeforces Round 301 Div.2 D)

    题意与分析(CodeForces 540D) 是一道概率dp题. 不过我没把它当dp做... 我就是凭着概率的直觉写的,还好这题不算难. 这题的重点在于考虑概率:他们喜相逢的概率是多少?考虑超几何分布 ...

  10. WEB中间件漏洞--IIS

    1.iis安装 版本 一直下一步,选上iis安装 端口修改 网站目录 通过网站发布目录(发布目录任意),新建index.html页面,可以正常访问 2.iis6.0解析漏洞 (1)文件名解析 IIS在 ...