2012-08-30 67 views
2

我是新來的線程在Java中,我需要從少數活動線程訪問數據結構。我聽說java.util.concurrent.ConcurrentHashMap對線程友好。在訪問ConcurrentHashMap時,我是否需要使用synchronized(map){} 或者它會自行處理鎖?使用ConcurrentHashMap

回答

4

它處理鎖本身,而事實上你必須給他們無權訪問(有沒有其他的選項)

可以在特殊情況下的寫入使用​​,但它是非常罕見的,你應該需要做這個。例如如果您需要實施自己的putIfAbsent,因爲創建對象的成本很高。

使用syncrhonized進行讀操作會失敗使用併發集合的目的。

+2

另外'putIfAbsent'執行原子,這在某些情況下,非常有用。 – stemm

2

簡答:不,您不需要使用synchronized(map)
龍回答:

  • 所有ConcurrentHashMap提供的操作是線程安全的,你可以叫他們不用擔心鎖定
  • 但是,如果你需要一些操作在你的代碼的原子,你仍然需要某種鎖定在客戶端
2

不,您不需要,但如果您需要依賴內部同步,則應該使用Collections.synchronizedMap來代替。來自javadoc的ConcurrentHashMap

該類與Hashtable在依賴其線程安全性但不依賴於其同步細節的程序中完全可互操作。

其實它不會對整個數據結構,但在它的子部分(一些桶)同步。 這意味着ConcurrentHashMap的迭代器是弱一致的,並且映射的大小可能不準確。 (但是另一方面,它的運行仍然是一致的,並且吞吐量更高)

+0

爲什麼有人需要在地圖上使用'.size()'?總不能老是值()'和'鍵設置()'以相同的方式,大小是不準確的? – dantuch

+0

@dantuch否 - 參考javadoc中的值,例如:*「集合由地圖支持,因此對地圖的更改反映在集合中,反之亦然。」* – assylias

3

ConcurrentHashMap僅適用於您不需要任何更多原子性而不是提供開箱即用的情況。例如,如果你需要得到的值,用它做什麼,然後設置一個新的值,都在一個原子操作,這不能沒有外部鎖定實現。

在所有這些情況下沒有任何東西可以在你的代碼替換明確的鎖,它只不過是浪費使用此實現,而不是基本HashMap的。

-1

還有一個更重要的功能要注意併發除併發功能它提供的功能,它是故障安全迭代器。只是因爲他們想要編輯的的entrySet PUT /而迭代刪除使用CHMP。 Collections.synchronizedMap(Map)是另一個。但是ConcurrentModificationException可能出現在上述情況中。