Java hashmap 只读线程安全

cod*_*ons 7 java hashmap thread-safety

我有这个代码,它有一个在静态块中初始化的共享哈希映射。我不公开哈希图,它以只读方式使用(get 和 containsKey)。我想确定这是否是线程安全的。

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

Kli*_*cou 11

假设new MyLoader().load()返回一个用所有数据完全初始化的映射,并且在此之后永远不会修改,那么所有线程同时从该映射中检索数据是安全的。HashMap 的 Javadoc 说:“如果多个线程同时访问一个哈希映射,并且至少有一个线程在结构上修改了映射,那么它必须在外部同步。” 因此,如果没有线程正在修改映射,则不必对其进行同步。

作为一种安全措施,您的load()方法应该强制执行不变性:

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

这样,您就不必担心您不熟悉的某些代码中的某些线程可能会无意中修改地图。就做不到了。