ConcurrentHashMap 原理分析
这篇文章仅分析ConcurrentHashMap 的安全性和并发性,hashMap的原理看java系列中的另一篇。
1. 成员
对比hashMap 和Concurrentmap 可以发现后者多了一个关键的对象Segment和一些该对象相关的属性
2.内部类
Concurrenthashmap 1.7 和hashmap的内部类相比,多出来了一个Segment 内部类,线程安全且高性能的实现多半和这个有关。
发现在Segment 中 继承了ReentrantLock 类,知道了这里使用的是加锁的方式来保证每个Segment操作的安全性,并且这个锁是加载每个Segment 上的
- Segment
Segment 内部维护了一个HashEntry 哈希表,还有一些维护哈希表的属性。
3. 方法
3. 1 构造方法
这里看默认的实现
ConcurrentHashMap
hashmap
concurrentHashMap 中多了一个并发级别的设置,默认是16
public ConcurrentHashMap(int initialCapacity,
float loadFactor, int concurrencyLevel) {
if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0)
throw new IllegalArgumentException();
if (concurrencyLevel > MAX_SEGMENTS)
concurrencyLevel = MAX_SEGMENTS;
// Find power-of-two sizes best matching arguments
int sshift = 0;
int ssize = 1;
while (ssize < concurrencyLevel) {
++sshift;
ssize <<= 1;
}
this.segmentShift = 32 - sshift;
this.segmentMask = ssize - 1;
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
int c = initialCapacity / ssize;
if (c * ssize < initialCapacity)
++c;
int cap = MIN_SEGMENT_TABLE_CAPACITY;
while (cap < c)
cap <<= 1;
// create segments and segments[0]
Segment<K,V> s0 =
new Segment<K,V>(loadFactor, (int)(cap * loadFactor),
(HashEntry<K,V>[])new HashEntry[cap]);
Segment<K,V>[] ss = (Segment<K,V>[])new Segment[ssize];
UNSAFE.putOrderedObject(ss, SBASE, s0)