码迷,mamicode.com
首页 > 其他好文 > 详细

ConcurrentHashMap

时间:2020-01-01 09:29:30      阅读:77      评论:0      收藏:0      [点我收藏+]

标签:move   一个   cas   vol   点的hash   shm   ola   循环   hash   

负载因子:元素个数>=桶个数*负载因子,则触发扩容。默认桶个数16,默认负载因子0.75。
HashMap的容量是2的幂次可以把哈希取模的操作变成位运算以加快运算速度,当length是2的幂次时,a%length <=> a&(length-1) (比如101101%1000 <=>101101&111 = 101)。

1.7 HashMap
哈希表,头插法
2个线程put,同时扩容会出现链表成环

1.7 ConcurrentHashMap
分段锁(段内扩容,重新hash),ReentrantLock

1.8 HashMap
哈希表,当链表达到一定长度则转化为红黑树
尾插法,避免2个线程put扩容链表成环

---------------------------------------------
1.8 ConcurrentHashMap
get操作不加锁,因为Node的val和next用volatile修饰,其它线程修改val或者新增结点修改next对get线程可见。
table数组用volatile修饰是保证扩容时的可见性(并发扩容)。

get方法
根据key计算hashcode找到对应的桶,如果在桶上(hashcode=桶结点的hashcode)则直接返回val。
如果桶结点是树的根节点,则按照树的方式找,
如果桶结点是链表首结点,则按照链表的方式找。
遍历时读取volatile修饰的next,找到时返回volatile修饰的val。

put方法
根据key计算hashcode
循环以下
如果table为空则初始化
根据hashcode找到桶,如果桶结点为空,则cas写入新的桶结点和值(原值null),退出循环
如果结点hashcode为MOVED(-1),说明正在扩容,则本线程帮助扩容
如果以上都不满足,则给桶加synchronized锁,尾插法写入数据

 

扩容
增加了ForwardingNode表示扩容中的结点,让其它写线程也来帮助扩容。
sizeCtl:0表示还未初始化,-1表示正在初始化,-N表示N-1个线程正在扩容,+N表示下一次扩容的大小。
扩容步骤
新建一个原来2倍的数组,把原数组的元素插入到新数组。

ConcurrentHashMap

标签:move   一个   cas   vol   点的hash   shm   ola   循环   hash   

原文地址:https://www.cnblogs.com/lankerenf3039/p/12128199.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!