concurrenthashmap jdk1.8
参考: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的更多相关文章
- ConcurrentHashMap(JDK1.8)为什么要放弃Segment
今天看到一篇博客:jdk1.8的HashMap和ConcurrentHashMap,我想起了前段时间面试的一个问题:ConcurrentHashMap(JDK1.8)为什么要使用synchronize ...
- Java泛型底层源码解析--ConcurrentHashMap(JDK1.7)
1. Concurrent相关历史 JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步容器将所有对容器状态的访问都串行化了,这样保证了线程的安全 ...
- 多线程-ConcurrentHashMap(JDK1.8)
前言 HashMap非线程安全的,HashTable是线程安全的,所有涉及到多线程操作的都加上了synchronized关键字来锁住整个table,这就意味着所有的线程都在竞争一把锁,在多线程的环境下 ...
- 6.ConcurrentHashMap jdk1.7
6.1 hash算法 就是把任意长度的输入,通过散列算法,变换成固定长度的输出,该输出就是散列值.这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所 ...
- Java并发编程总结4——ConcurrentHashMap在jdk1.8中的改进(转)
一.简单回顾ConcurrentHashMap在jdk1.7中的设计 先简单看下ConcurrentHashMap类在jdk1.7中的设计,其基本结构如图所示: 每一个segment都是一个HashE ...
- Java并发编程总结4——ConcurrentHashMap在jdk1.8中的改进
一.简单回顾ConcurrentHashMap在jdk1.7中的设计 先简单看下ConcurrentHashMap类在jdk1.7中的设计,其基本结构如图所示: 每一个segment都是一个HashE ...
- ConcurrentHashMap原理分析(1.7与1.8)
前言 以前写过介绍HashMap的文章,文中提到过HashMap在put的时候,插入的元素超过了容量(由负载因子决定)的范围就会触发扩容操作,就是rehash,这个会重新将原数组的内容重新hash到新 ...
- 并发容器和框架之ConcurrentHashMap
了解HashMap的人都知道HashMap是线程不安全的(多线程下的put方法达到一定大小,引发rehash,导致闭链,最终占满CPU),同时线程安全的HashTable效率又令人望而却步(每个方法都 ...
- 深入解析ConcurrentHashMap类
以前写过介绍HashMap的文章,文中提到过HashMap在put的时候,插入的元素超过了容量(由负载因子决定)的范围就会触发扩容操作,就是rehash,这个会重新将原数组的内容重新hash到新的扩容 ...
随机推荐
- (杭电 1702)ACboy needs your help again!
ACboy needs your help again! Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Jav ...
- 指针小白:修改*p与p会对相应的地址的变量产生什么影响?各个变量指针的长度为多少?
这两天敲代码碰到了一个这样的问题 代码如下: #include <stdio.h> #include <stdlib.h> int main() { ; int* p=& ...
- 推荐 的FPGA设计经验(4) 时钟和寄存器控制架构特性使用
Use Clock and Register-Control Architectural Features FPGAs provide device-wide clocks and register ...
- mybatis入门(三):mybatis的基础特性
mybatis的知识点: 1.mybatis和hibernate本质区别和应用场景 hibernate:是一个标准的ORM框架(Ojbect relation mapper对象关系映射).入门门槛较高 ...
- 【NAS】NFS中的fsid如何理解
最近在NAS项目中遇到对NFS的fsid有点疑惑.就深入了解一番 在nfs的配置文件/etc/exports中,fsid作为一个共享参数,具体含义如下: 格式: fsid=num|root|uuid ...
- P1535 游荡的奶牛
P1535 游荡的奶牛 题目描述 Searching for the very best grass, the cows are travelling about the pasture which ...
- vim中project多标签和多窗口的使用
1.打开多个窗口 打开多个窗口的命令以下几个: 横向切割窗口 :new+窗口名(保存后就是文件名) :split+窗口名,也可以简写为:sp+窗口名 纵向切割窗口名 :vsplit+窗口名,也可以简写 ...
- MySQL数据库优化方法
一.表类型MyISAM 和 InnoDB的区别 作者:Oscarwin链接:https://www.zhihu.com/question/20596402/answer/211492971来源:知乎著 ...
- 【shell 练习3】用户管理脚本(一)
一.创建十个用户,密码为八位 [root@localhost ~]# cat UserManger02.sh #!/bin/bash . /etc/init.d/functions [ $UID -n ...
- poj 2155 (二维树状数组 区间修改 求某点值)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 33682 Accepted: 12194 Descript ...