五分钟搞定Java并发编程之ConcurrentHashMap(带你装B带你飞!)

更新时间:2023-05-16 04:27:04 阅读: 评论:0

五分钟搞定Java并发编程之ConcurrentHashMap(带你装B带你飞!)
引⾔
ConcurrentHashMap是线程安全并且⾼效的HashMap,在并发编程中经常可见它的使⽤,在开始
分析它的⾼并发实现机制前,先讲讲废话,看看它是如何被引⼊jdk的。
bachelordom
为什么引⼊ConcurrentHashMap?
HashMap线程不安全,它的线程不安全主要发⽣在put等对HashEntry有直接写操作的地⽅:
拉拉岛
HashMap线程不安全操作源码⽰例
从put操作的源码不难看出,线程不安全主要可能发⽣在这两个地⽅:
key已经存在,需要修改HashEntry对应的value;
key不存在,在HashEntry中做插⼊。
爱丽丝梦游仙境片尾曲Hashtable线程安全,但是效率低下:
Hashtable源码⽰例.png
downtonabbey从Hashtable⽰例的源码可以看出,Hashtable是⽤synchronized关键字来保证线程安全的,由于synchronized的机制是在同⼀时刻只能有⼀个线程操作,其他的线程阻塞或者轮询等待,在线程竞争激烈的情况下,这种⽅式的效率会⾮常的低下。
注:⼩⼩的多嘴⼀句,Hashtable扩容的时候newSize = 2 * oldSize + 1,这个是常识性的点,但是由于整个jdk源码封装⽐较好,⽽且Hashtable效率低下,使⽤较少,貌似好多程序员都不太知道这⼀点。
ConcurrentHashMap的为什么⾼效?
Hashtable低效主要是因为所有访问Hashtable的线程都争夺⼀把锁。如果容器有很多把锁,每⼀把锁控制容器中的⼀部分数据,那么当多个线程访问容器⾥的不同部分的数据时,线程之前就不会存在锁的竞争,这样就可以有效的提⾼并发的访问效率。这也正是ConcurrentHashMap使⽤的分段锁技术。将ConcurrentHashMap容器的数据分段存储,每⼀段数据分配⼀个Segment(锁),当线程占⽤其中⼀个Segment时,其他线程可正常访问其他段数据。ConcurrentHashMap实现分析
在分析ConcurrentHashMap的源码之前先来看看它的结构:
免费视频教程ConcurrentHashMap类图
从类图可以看出:ConcurrentHashMap由Segment和HashEntry组成。
Segment是可重⼊锁,它在ConcurrentHashMap中扮演分离锁的⾓⾊;
HashEntry主要存储键值对;
CurrentHashMap包含⼀个Segment数组,每个Segment包含⼀个HashEntry数组并且守护它,当修改HashEntry数组数据时,需要先获取它对应的Segment锁;⽽HashEntry数组采⽤开链法处理冲突,所以它的每个HashEntry元素⼜是链表结构的元素。
由此可以得出ConcurrentHashMap的结构图如下:
ConcurrentHashMap结构图初始化ConcurrentHashMap
ConcurrentHashMap构造⽅法
可以看出,ConcurrentHashMap的构造⽅法都调⽤了public ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel),初始化部分都由它来完成,我们来看⼀看它是怎么来初始化ConcurrentHashMap的。
ConcurrentHashMap初始化具体实现
整个初始化是通过参数initialCapacity,loadFactor和concurrencyLevel来初始化gmentShift(段偏移量)、gmentMask(段掩码)和gment数组。
张江集团学校
ConcurrentHashMap初始化具体实现
计算gment数组长度公主日记2片尾曲
gment数组长度ssize是由concurrencyLevel计算得出,当ssize < concurrencylevel时,ssize="" *="">
注:concurrencyLevel的最⼤值是65535,那么,ssize的最⼤值就为65536,对应到⼆进制就是16位。
初始化gmentShift、gmentMask
gmentShift和gmentMask在定位gment使⽤,gmentShift = 32 - ssize向左移位的次
数,gmentMask = ssize - 1。ssize的最⼤长度是65536,对应的 gmentShift最⼤值为
16,gmentMask最⼤值是65535,对应的⼆进制16位全1;
病人的英文初始化gment、
1、初始化每个gment的HashEntry长度;fun run
2、创建gment数组和gment[0]。
马丁路德金 我有一个梦想注:HashEntry长度cap同样也是2的N次⽅,默认情况,ssize = 16,initialCapacity =
16,loadFactor = 0.75f,那么cap = 1,threshold = (int) cap * loadFactor = 0。
Segment定位
Hash算法
ConcurrentHashMap使⽤分段锁gment来保护数据,也就是说,在插⼊和读取元素,需要先通

本文发布于:2023-05-16 04:27:04,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/78/649565.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:线程   数组   数据   需要
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图