Java1.7下的ConcurrentHashMap【简要总结】
来源:互联网 发布:c语言从单数1加到100 编辑:程序博客网 时间:2024/05/29 16:41
ConcurrentHashMap是线程安全的,通过分段锁的方式提高了并发度。分段是一开始就确定了,后期不能再进行扩容。
其中段Segment继承了重入锁ReentrantLock,有了锁的功能,同时含有类似HashMap的数组加链表的结构。
虽然Segment的个数是不能扩容的,但是单个Segment里面的数组是可以扩容的。
ConcurrentHashMap有3个参数:
initialCapacity:初始总容量:默认16
loadFactor:加载因子,默认0.75
concurrencyLevel:并发级别,默认16
然后我们需要知道的是:
segment的个数即ssize
取大于等于并发级别的最小的2的幂次。如concurrencyLevel=16,那么ssize=16,如concurrencyLevel=10,那么ssize=16。
单个segment的初始容量cap
c=initialCapacity/ssize,并且可能需要+1(即向上取整)。如15/7=2,那么c取3,如16/8=2,那么c取2。cap取的值就是大于等于c的最小2的幂次。但是cap最小值要求是2。
单个segment的阈值threshold
通过cap*loadFactor计算得出。
所以,默认情况下,segment的个数ssize=16,每个segment的初始容量是cap=2,单个segment的阈值threshold=1。
put过程
1、首先根据key计算出一个hash值,找到对应的Segment
2、调用Segment的lock方法,为后面的put操作加锁
3、根据key计算出hash值,找到Segment中数组中对应的index的链表,并将该数据放置到链表中
4、判断当前Segment包含元素的数量大于阈值,则Segment进行扩容
扩容过程
这个扩容过程是在Segment的锁的保护下进行扩容的,不需要关注并发问题。
这里的重点就是:
首先找到一个lastRun,lastRun之后的元素和lastRun是在一个桶中,所以后面的不需要进行变动。
然后对开始到lastRun部分的元素,重新计算下设置到newTable中,每次都是将当前元素作为newTable的首元素,之前老的链表作为该首元素的next部分。
get过程
1、通过key计算出对应的segment
2、再根据key计算出对应segment中数组的index
3、最终遍历上述index位置的链表,查找出对应的key的value
- Java1.7下的ConcurrentHashMap【简要总结】
- Java1.8下的ConcurrentHashMap【简要总结】
- 【简要总结】Java1.8下的HashMap
- ConcurrentHashMap、CopyOnWriteArrayList的简要总结:
- Java1.7ConcurrentHashMap类源码解析
- ConcurrentHashMap 总结( 下 )
- ConcurrentHashMap 总结( 下 )
- java1.8 -ConcurrentHashMap
- [Java并发包学习八]深度剖析ConcurrentHashMap-java1.7
- ConcurrentHashMap实现原理总结--下
- Java1.8之ConcurrentHashMap源码
- ConcurrentHashMap 原理简要分析
- 总结我学过的java1。
- linux下安装java1.5的源
- JAVA1.7的新特性
- java1.7的新特性
- 集合源码总结(java1.7)
- 集合源码总结(java1.7)
- WebView读取SD卡上的HTML
- 最短路计数(Shortest Path Count)
- 栈&队列&栈帧&递归
- 三种快速排序算法以及快速排序的优化
- 编译原理学习笔记---语法
- Java1.7下的ConcurrentHashMap【简要总结】
- 并查集(Union-Find Set)模板
- tk库的使用
- 继原创保护功能开通之后,又开通赞赏功能
- postman测试post请求参数为json类型
- 编译原理学习笔记---自上而下分析
- 邮递员送信(letter)
- pico-ctf 2013 overflow-4
- 【Unity】【转】四元数(Quaternion)和旋转