博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
锁分段技术、ConcurrentHashMap、扩容
阅读量:7126 次
发布时间:2019-06-28

本文共 1163 字,大约阅读时间需要 3 分钟。

  hot3.png

什么是锁分段技术?

  ConcurrentHashMap是使用的锁分段技术,锁分段技术就是说容器里有多把锁,每一把锁用于锁容器其中一部分数据,多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效的提高并发访问效率。然后在ConcurrentHashMap中,它首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。

ConcurrentHashMap是由Segment数组结构和HashEntry数组结构组成。Segment继承了ReentrantLock,是一种可重入锁ReentrantLock(可重入锁,也叫做递归锁,指的是同一线程外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响。在JAVA环境下 ReentrantLock 和synchronized 都是可重入锁),在ConcurrentHashMap里扮演锁的角色,HashEntry则用于存储键值对数据。一个ConcurrentHashMap里包含一个Segment数组,Segment的结构和HashMap类似,是一种数组和链表结构, 一个Segment里包含一个HashEntry数组,每个HashEntry是一个链表结构的元素, 每个Segment守护着一个HashEntry数组里的元素,当对HashEntry数组的数据进行修改时,必须首先获得它对应的Segment锁。

源码:初始化segmentShift和segmentMask,初始化Segment。

put方法里需要对共享变量进行写入操作,所以为了线程安全,在操作共享变量时必须得加锁。Put方法首先定位到Segment,然后在Segment里进行插入操作。插入操作需要经历两个步骤,第一步判断是否需要对Segment里的HashEntry数组进行扩容,第二步定位添加元素的位置然后放在HashEntry数组里

是否需要扩容?

在插入元素前会先判断Segment里的HashEntry数组是否超过容量(threshold),如果超过阀值,数组进行扩容。值得一提的是,Segment的扩容判断比HashMap更恰当,因为HashMap是在插入元素后判断元素是否已经到达容量的,如果到达了就进行扩容,但是很有可能扩容之后没有新元素插入,这时HashMap就进行了一次无效的扩容。

如何扩容。

扩容的时候首先会创建一个两倍于原容量的数组,然后将原数组里的元素进行再hash后插入到新的数组里。为了高效ConcurrentHashMap不会对整个容器进行扩容,而只对某个segment进行扩容。

转载于:https://my.oschina.net/134596/blog/668395

你可能感兴趣的文章
Sql Server函数全解<四>日期和时间函数
查看>>
Elasticsearch: 权威指南 &#187; 深入搜索 &#187; 多字段搜索 &#187; 多数字段 good
查看>>
SQL Server里的INTERSECT ALL
查看>>
log4j直接输出日志到flume
查看>>
TP-LINK telnet远程 重启路由器(转)
查看>>
apache tomcat 集群! (转)
查看>>
nginx隐藏版本号
查看>>
用jquery删除table列表中&lt;u&gt;标签
查看>>
医学院学生可以用VR技术来模拟人体解剖试验了
查看>>
Kafka的安装测试
查看>>
Bash shell 程式的结构
查看>>
PostgreSQL 数据库NULL值的默认排序行为与查询、索引定义规范 - nulls first\last, asc\desc...
查看>>
苏宁 IT 总部消费者研发中心许宏平:如何用“黑科技”做“懂你”的门店?
查看>>
SharePoint 使用脚本为表单绑定事件
查看>>
好好的家电公司戴森,怎么说造车就造车了?
查看>>
物联网如何保持 Ben&Jerry 店冰淇淋不融化
查看>>
SQL Agent服务无法启动如何破
查看>>
为什么System.Attribute的GetHashCode方法需要如此设计?
查看>>
如何回答这三个问题 反映着事件响应小组的准备程度
查看>>
网上挂号众口难调 医院信息系统待整合
查看>>