2012-09-16 73 views
3

我在看文檔的java.util.HashMap,和它說:HashMap:多線程訪問多個閱讀器和一個單一作者的安全嗎?

如果多個線程同時訪問該地圖,並 線程至少一個結構上修改了地圖,它必須保持外部同步 。

「it」是什麼意思?「it」可能被解釋爲表示修改地圖的線程,或者它可能意味着地圖本身。

無論是「多線程閱讀安全」還是「只有單一線程安全時纔有安全作者」的情況下,都沒有膽小鬼(至少對我來說),這讓我相信稱之爲「多讀者和單寫作者「在文檔中特定的情況意味着該語句應該被解釋爲」安全地具有多個線程讀取和單個線程寫入「,而不是毫不費力的」在有作者時鎖定所有內容「。

更何況,在.NET中的散列表實施方案是(明確)記錄爲:

Hashtable是線程安全的使用由多個讀線程和一個寫線程

(的。 Net類在默認情況下不是線程安全的),所以必須有「多個讀取器線程和一個寫入器線程」的情況。

+0

*它*是'HashMap'。 – oldrinb

+0

同步一個線程是沒有意義的。您可以通過同步對象來管理線程的訪問。這是基本的Java。我沒有看到.NET與它有什麼關係。 – EJP

回答

2

當線程「在結構上修改地圖」時,內部元素處於不確定狀態,因此可能會影響讀取。因此,需要使用映射外部的某種方法來同步讀取和寫入。

也許.NET庫的編寫者在更新期間更加小心地保持其內部結構處於確定狀態。

+0

感謝您的回答! – daniel

0

地圖本身。 HashMap不是線程安全的。

看看ConcurrentHashMap,它是一個線程安全的地圖。

你也可以自己管理它。該代碼可能看起來像下面

class SomeClass { 

    private Map<Object, Object> map = new HashMap<Object, Object>(); 

    public synchronized void put(Object key, Object value) { 
     map.put(key, value); 
    } 

    public synchronized Object get(Object key) { 
     return map.get(key); 
    } 
} 

更安全,返回值對象的副本,以避免意外的行爲。

public synchronized ValueType get(Object key) { 
    return map.get(key).clone(); // assume that the ValueType implements Cloneable 
    // of course, you can return a copy in many ways you like 
} 

這將只允許put方法來修改地圖。所有的操作都是線程安全的。

+0

嗨@scarcer。 「HashMap不是線程安全的」語句並不完全正確。是一個HashMap實例是:
- 保證是線程安全的,當所有線程都在做讀操作
- 當多個線程正在做concurent寫操作並不安全
- [上面這個問題]:當concurently,多線程正在讀取,並且有一個線程正在寫入 – daniel

+0

@daniel「當所有線程正在執行讀取操作時,HashMap實例保證是線程安全的」,這是不正確的。見Mark的答案。 –

+0

@丹尼爾,史蒂夫郭,這裏是我的看法。如果所有線程都在進行讀取操作(這意味着不僅要讀取地圖,還要讀取從地圖上讀取的元素),因爲地圖的結構和地圖的元素不會改變,當然我們可以期望每個線程都可以獲得相同的值。但是如果結構或元素本身發生了變化,它將不再是線程安全的。最安全的方法是:同步您的讀取方法,並返回值對象的副本。請看我的帖子。 – scarcer

相關問題