2017-02-22 69 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); 
} 

这样,您就不必担心,在一些代码中的一些线程你不熟悉可能在无意中修改地图。它将无法。