ConcurrentHashMap實現分析

java5中新增了ConcurrentMap接口和它的一個實現類ConcurrentHashMap.該類在多線程併發情況下的效率要比HashTable和Collections.synchronizedMap()返回的map效率要高。原因是它的鎖實現的很“機智”。
HashTable和Collections的內部類SynchronizedMap裏的同步,都是用synchronized來實現的,每次都是鎖整個表,因此同一時刻只能有一個線程操作hash表。
而ConcurrentHashMap中使用了Segment[]來存儲數據,Segment繼承自ReentrantLock類(這樣執行lock操作就方便了),默認情況下有16個Segment,當put數據時,會看這個key的hash值對應到哪個Segment裏面,然後只鎖這個Segement,所以它允許多個線程同時put。(讀操作一般不需要加鎖,除非發生特殊情況)
Segemnt

/**
* The segments, each of which is a specialized hash table
*/
final Segment<K,V>[] segments;

/**
* Segments are specialized versions of hash tables. This
* subclasses from ReentrantLock opportunistically, just to
* simplify some locking and avoid separate construction.
*/
static final class Segment<K,V> extends ReentrantLock implements Serializable {



ConcurrentHashMap的put()方法:

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);
}

/**
* Returns the segment that should be used for key with given hash
* @param hash the hash code for the key
* @return the segment
*/
final Segment<K,V> segmentFor(int hash) {
return segments[(hash >>> segmentShift) & segmentMask];
}

先根據key的hash值計算所屬的Segment,然後執行該Segment的put()方法。

Segemnt的put()方法:

V put(K key, int hash, V value, boolean onlyIfAbsent) {
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 {
unlock();
}
}

由於Segment繼承自ReentrantLock,因此可以很方便的調用lock()和unlock().

綜述,由於ConcurrentHashMap採用了分段鎖(或者說鎖分離),並且對存儲size等操作做了一些加鎖優化,因此其效率要高一些。重點還是分段鎖。

有一篇介紹ConcurrentHashMap的文章,分享一下:
[url]http://www.iteye.com/topic/344876[/url]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章