ConcurrentHashMap 原理解析
ConcurrentHashMap 原理解析
ConcurrentHashMap.class
其他配套信息,初始化构造函数
内部类 static class Segment<K,V> extends ReentrantReadWriteLock implements Serializable
所有增删改
1,初始化: 构造函数创建segements空间,并且对每个segement创建table
2,操作:操作时根据key找到segement(内部类),
3,对于put操作等,引入就锁lock(读写锁),先根据key进行hash算法找到segement,然后在桶中找到这个桶的table中的第一个,
再根据这第一个遍历,找到了就覆盖返回旧值,没找到就新增
(由于这个table[index]存的是entry这是一个单链表结构,这样获取第一个(table[index])之后可以马上对其遍历)
transient volatile HashEntry<K,V>[] table;//忽略这个成员变量序列化
//由于这个table是内部类,每new Segment一个桶就有一个table变量在里面,由于就是属于这个内部类的所以类似threadlocal效果,
//对于大类将有一个内部类,那么大类操作这个内部类就相当于threadlocal变量
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;
}
segmentShift = 32 - sshift;
segmentMask = ssize - 1;
this.segments = Segment.newArray(ssize);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
int c = initialCapacity / ssize;
if (c * ssize < initialCapacity)
++c;
int cap = 1;
while (cap < c)
cap <<= 1;
for (int i = 0; i < this.segments.length; ++i)
this.segments[i] = createSegment(cap, loadFactor);
}
protected Segment<K, V> createSegment(int initialCapacity, float lf) {
return new Segment<K, V>(initialCapacity, lf);
}
Segment(int initialCapacity, float lf) {
loadFactor = lf;
setTable(HashEntry.<K,V>newArray(initialCapacity));
}
void setTable(HashEntry<K,V>[] newTable) {
threshold = (int)(newTable.length * loadFactor);
table = newTable;
}
public V put(K key, V value) {
if (value == null)
throw new NullPointerException();
int hash = hash(key.hashCode());
return segmentFor(hash).put(key, hash, value, false);
}
public V put(K key, V value) {
if (value == null)
throw new NullPointerException();
int hash = hash(key.hashCode());
return segmentFor(hash).put(key, hash, value, false);
}
V put(K key, int hash, V value, boolean onlyIfAbsent) {
writeLock().lock();
try {
int c = count;
if (c++ > threshold) // ensure capacity
rehash();
HashEntry<K,V>[] tab = table;
int index = hash & (tab.length - 1);
HashEntry<K,V> first = tab[index];
HashEntry<K,V> e = first;
while (e != null && (e.hash != hash || !key.equals(e.key)))
e = e.next;
V oldValue;
if (e != null) {
oldValue = e.value;
if (!onlyIfAbsent)
e.value = value;
}
else {
oldValue = null;
++modCount;
tab[index] = new HashEntry<K,V>(key, hash, first, value);
count = c; // write-volatile
}
return oldValue;
} finally {
writeLock().unlock();
}
}