2012-01-29 62 views
4

get(Key)方法調用AA標準HashMapConcurrentHashMap等於在性能時,沒有修改發生的墊層地圖(因此只得到()操作?執行)Java併發:都是「獲得(鍵)HashMap和ConcurrentHashMap的性能等於

更新與背景:

併發是一個相當KOMPLEX話題:我做NEAD「併發/ threadsafety」,但只有在放,這種情況發生非常很少而對於賣出期權,我可以交換地圖關聯。本身(這是原子和線程安全的)。因此,我問我正在做很多get(並且可以選擇使用HashMa來實現它p(創建一個臨時HashMap,將數據複製到新的HashMap和交換關聯中)或使用ConcurrentHashMap ...由於我的應用程序真的有很多獲取我想了解更多有關如何使用兩種不同獲取方式來消除性能的問題。這聽起來很愚蠢,因爲互聯網上有很多不必要的信息,但我認爲這可能會讓很多人感興趣。所以如果有人知道ConcurrentHashMap的內部工作得到它會很好回答這個問題。

非常感謝!

+2

ConcurrentHashMap是線程安全的。這伴隨着每一項操作的開銷。但是,除非您的應用程序花費90%的時間從中檢索值,否則您不會注意到其中的差異。 – bdares 2012-01-29 03:29:59

+0

你好,爲什麼我會得到一個downvote?請解釋爲什麼! – user1145216 2012-01-29 03:30:02

+0

你看看API嗎?它清楚地表明寫入是同步的,而檢索不是。還有什麼要知道的? – blackcompe 2012-01-29 06:34:51

回答

2

你可以看看源代碼。 (我期待在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; 
    } 

凡散列()做一些額外的轉換和異或「改善」的哈希碼。

ConcurrentHashMap.get()是更復雜一些,但不是很多

public V get(Object key) { 
    int hash = hash(key.hashCode()); 
    return segmentFor(hash).get(key, 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中組織好一點。所以我猜測性能足夠相似。

這就是說,如果真的是非常罕見的,你可以考慮實現一個「複製寫入」類型的機制。

2

根據ConcurrentHashMap API,檢索方法沒有鎖定。所以,我會說他們在表現上是平等的。

3

你在問錯誤的問題。

如果你需要併發性,你需要它不管的性能影響。

正常行爲的程序幾乎總是比快速程序排名更高。我說「幾乎總是」,因爲可能有商業上的理由來發布帶有錯誤的軟件,而不是直到錯誤得到修復才能保留下來。