2017-02-22 101 views
1

我有這個代碼,它具有在靜態塊中初始化的共享哈希映射。我不公開hashmap,它使用只讀(get和containKey)。 我想確定這是否是線程安全的。Java HashMap只讀線程安全

public class MyClass { 
    private static final Map<String, MyObject> myMap; 

    static { 
     myMap = new MyLoader().load() 
    } 

    public MyClass() { 
     if (containsKey(someKey)) { 
      // do something 
     } 
     myMap.get(something) 
    } 

    static boolean containsKey(String key) { 
     // do some other stuff 
     return myMap.containsKey(key) 
    } 
} 
+0

只要沒有線程正在修改映射(添加或刪除鍵/值對,或變更現有值),而其他線程正在讀取則線程安全。我沒有包括突變關鍵對象,因爲這會導致問題,無論線程是什麼。 –

+0

它沒有被暴露,並且在類中沒有被修改 –

+0

該方法在寫入映射的整個應用程序中調用'new MyLoader()。load()'_only_事物,並且它是否只寫入一個電話? –

回答

2

假設new MyLoader().load()返回一個地圖,完全與所有數據初始化,這絕不會被修改後,那麼它是安全的所有線程從這個地圖檢索數據併發。 HashMap的Javadoc說:「如果多個線程同時訪問哈希映射,並且至少有一個線程在結構上修改了映射,那麼它必須在外部同步。」因此,如果沒有線程正在修改地圖,則不需要進行同步。

爲安全起見,你load()方法應該執行不變性:

public Map<String, MyObject> load() { 
    Map<String, MyObject> mymap = new HashMap<>(); 
    mymap.put(...); 
    ... 
    return Collections.unmodifiableMap(mymap); 
} 

這樣,您就不必擔心,在一些代碼中的一些線程你不熟悉可能在無意中修改地圖。它將無法。