2012-11-14 57 views
3

併發更新非同步HashMap顯然會導致活鎖或其他數據損壞;爲了避免這種情況,應該使用併發版本或實現同步機制。Java:可以從HashMap中讀取狀態嗎?

可併發往HashMap.get()變化HashMap中的狀態的呼叫,像老調重彈?

更新:

有網友評論想知道這個問題的實際問題時,除了與挑剔的數據結構行爲理論的喜悅。

如果get()不改變HashMap的狀態(並且不能導致另一個reaseon的活鎖),那麼比單個線程可以提前創建一個HashMap,然後許多線程可以同時讀取它。如果併發讀取並不安全,我們需要ConcurrentHashMap,每多線程訪問,無論其類型。

+0

爲什麼這對你很重要? – vainolo

+1

我心愛的數據結構的一般知識。 –

+2

http://www.docjar.com/html/api/java/util/HashMap.java.html – amit

回答

1

Javadoc中通常定義什麼被認爲是映射的結構修飾。 HashMap指出get不是會引起結構修改的操作。

然而,其他的映射實現不同的表現。例如,a LinkedHashMap可以使用在這種情況下是get一個結構修改訪問順序:

在訪問順序鏈接的哈希映射中,僅詢問與獲取地圖是結構修改。

0

如果你知道里面有什麼HashMap.get()發生的事情(這是一個具體的實現Map接口),可以讀取執行的代碼。

但你不應該關心它功能如何實現的,什麼是所有目的!唯一重要的是函數能夠達到它的合約(API +類/函數javadocs)。實施可能會在未來發生變化,因此取決於它是不好的做法。

+1

但這不是一個實現特定的問題。知道是否可以從多線程訪問'get()'的'HashMap'或者是否應該同步是非常重要的。我能想到它的許多用途。 – amit

+0

如果您要在併發環境中使用您的'Map',爲什麼不使用併發集合:['ConcurrentHashMap'](http://docs.oracle.com/javase/6/docs/api/java/util /concurrent/ConcurrentHashMap.html) – vainolo

+1

因爲如果你只需要併發讀取 - 避免使用'ConcurrentHashMap'的開銷可能是一件好事。 – amit

4

java docs

如果多個線程同時訪問一個散列映射,和至少一個 螺紋的修改地圖結構,它必須保持外部同步 。 (結構上的修改是指添加或刪除一個或多個映射的操作;僅改變與該一個實例已經包含一個鍵相關聯的值不被結構上的修改。)

它意味着併發get()是精細和不會導致狀態的改變。

此外,您可以隨時查看source瞭解更多關於它是如何構建的。

+0

+1我找不到參考;-)不同的地圖實現可能定義什麼結構修改是不同的(cf linkedhashmap),但在hashmap的情況下,'get'不是一個結構修改。 – assylias

+0

+1從邏輯上講,至少有一個寫入器線程需要同步的事實並不意味着只有讀取器線程不需要它。 –

0

只有調用get()肯定不會導致任何問題,因爲你在說。但是,併發的未同步更新肯定會導致這種情況。在get()方法中,只會在成員之前調用hashcode()方法,直到找到匹配項爲止。在這種情況下不會進行更新。

相關問題