![](/img/trans.png)
[英]Java ConcurrentHashMap is better than HashMap performance wise?
[英]Java Concurrency: Are "get(Key) for HashMap and ConcurrentHashMap equal in performance?
當沒有對底層Map進行修改時, get(Key)
方法調用標准HashMap
和ConcurrentHashMap
的性能相同(因此只執行get()操作。)
使用背景更新:
並發性是一個非常復雜的話題:我確實“並發/線程安全”,但只有看跌期權,這種情況極少發生。 對於看跌期權我可以交換地圖關聯本身(原子和線程安全)。 因此,我要求我做了很多獲取(並且可以選擇使用HashMap(創建臨時Hashmap,將數據復制到新的HashMap,交換關聯)或使用ConcurrentHashMap實現它...作為我的應用程序真的我想了解更多關於性能如何隨着不同的獲取而丟失。這聽起來很愚蠢,互聯網上有太多不必要的信息,但我覺得這可能會引起更多人的興趣。所以,如果有人知道ConcurrentHashMap的內部工作原理,那么回答這個問題會很棒。
非常感謝!
你問的是錯誤的問題。
如果您需要並發性, 無論性能影響如何,都需要它。
一個正確行為的程序幾乎總是比一個更快的程序排名更高。 我說“幾乎總是”因為可能有商業原因要發布帶有錯誤的軟件,而不是在錯誤得到修復之前保留。
根據ConcurrentHashMap
API,檢索方法沒有鎖定。 所以,我會說他們的表現相同。
你可以查看源代碼。 (我正在看JDK 6)HashMap.get()非常簡單:
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}
其中hash()執行一些額外的移位和XORing以“改進”您的哈希碼。
ConcurrentHashMap.get()有點復雜,但不是很多
public V get(Object key) {
int hash = hash(key.hashCode());
return segmentFor(hash).get(key, hash);
}
同樣,hash()做了一些移位和異或。 setMentFor(int hash)執行簡單的數組查找。 唯一復雜的東西是在Segment.get()中。 但即使這看起來不像火箭科學:
V get(Object key, int hash) {
if (count != 0) { // read-volatile
HashEntry<K,V> e = getFirst(hash);
while (e != null) {
if (e.hash == hash && key.equals(e.key)) {
V v = e.value;
if (v != null)
return v;
return readValueUnderLock(e); // recheck
}
e = e.next;
}
}
return null;
}
獲取鎖定的一個地方是readValueUnderLock()。 評論說,這在內存模型下在技術上是合法的,但從未發生過。
總的來說,看起來兩者的代碼非常相似。 在ConcurrentHashMap中組織得更好一些。 所以我猜測性能足夠相似。
也就是說,如果看跌非常罕見,您可以考慮實施“寫入時復制”類型的機制。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.