ConcurrentHashMap
ConcurrentHashMap特点
ConcurrentHashMap是Map接口在并发中常用的子类。该类采用分段锁的机制,优化了并发情况下效率低下的问题。分段锁是一个Map中添加了多个锁。
ConcurrentHashMap结构
ConcurrentHashMap中存储了一个Segment的数组。每个Segment中存放了一个HashEntry,类似于HashMap。
结构图如下:
ConcurrentHashMap初始化
ConcurrentHashMap初始化有三个参数:
- initialCapacity 初始化容量,每个Segment中的数组的长度。
- loadFactor 负载因子
- concurrencyLevel 并发级别。多少个Segment的,是2的N次方数。
Segment定位
通过两次哈希确定Segment的位置。
get操作
get获取结果时不进行添加锁,直接获取。为了保持数据的准确性,将值的通过volatile进行修饰,保持可见性,确保不会获取到过期数据。多个线程同时访问时volatile修饰的变量,添加、修改和删除操作比获取优先级高,所以不会出现过期数据。
当获取的数据是空值时,会进行加锁进行重读操作。
put操作
put操作时不会对所有数据进行加锁操作,而是针对具体的segment进行加锁操作。先定位到具体的Segment,然后添加锁。
put操作类似与hashMap的添加操作,需要考虑扩容的情况。
当添加时key或者value为null,直接返回空指针异常。
size操作
获取数量个数时,不会对整个数据进行加锁然后获取长度。而是针对每个segment都不进行加锁的情况下,多次获取每个Segment的长度,进行累加。如果有连续两次结果一致,返回累计长度。遍历结束后(遍历的此时为3次), 仍然都不一致的情况下,再进行加锁计算。
统计两次segment的长度是否一致的方法,不是根据size是否一致,而是根据每个segment的更新数据量是否一致,如果连续两次每个segment的更新量一致,结束。
引用: