我有这个代码,它在静态块中初始化了一个共享哈希映射。我没有公开hashmap,它使用只读(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)
}
}
答案 0 :(得分:4)
假设new MyLoader().load()
返回一个完全使用所有数据初始化的映射,并且之后从未修改过,那么所有线程都可以安全地同时从此映射中检索数据。 HashMap的Javadoc说:“如果多个线程同时访问一个哈希映射,并且至少有一个线程在结构上修改了映射,那么它必须在外部进行同步。”因此,如果没有线程正在修改地图,那么就不必同步它。
作为一项安全措施,您的load()
方法应强制执行不变性:
public Map<String, MyObject> load() {
Map<String, MyObject> mymap = new HashMap<>();
mymap.put(...);
...
return Collections.unmodifiableMap(mymap);
}
这样,您不必担心某些您不熟悉的代码中的某些线程可能会无意中修改了地图。它将无法实现。