我已经阅读了很多,但是还没有找到确切的答案。
我有一堂课,看起来像这样:
public class Foo() {
private static final HashMap sharedData;
private final HashMap myRefOfInnerHashMap;
static {
// time-consuming initialization of sharedData
final HashMap innerMap = new HashMap;
innerMap.put...
innerMap.put...
...a
sharedData.put(someKey, java.util.Collections.unmodifiableMap(innerMap));
}
public Foo(String key) {
this.myRefOfInnerHashMap = sharedData.get(key);
}
public void doSomethingUseful() {
// iterate over copy
for (Map.Entry entry : this.myRefOfInnerHashMap.entrySet()) {
...
}
}
}
而且我想知道从Foo实例访问sharedData是否是线程安全的(如构造函数和doSomethingUseful()中所示)。Foo的许多实例将在多线程环境中创建。
我的意图是在静态初始化程序中初始化sharedData,此后不进行修改(只读)。
我读到的是,不可变对象本质上是线程安全的。但是我仅在实例变量的上下文中看到了这一点。不变静态变量线程安全吗?
我发现的另一个构造是ConcurrentHashMap。我可以使sharedData的类型为ConcurrentHashMap,但是它包含的HashMaps是否也必须为ConcurrentHashMap类型?基本上..
private static final ConcurrentHashMap sharedData;
要么
private static final ConcurrentHashMap sharedData;
还是更安全(简单地clone()会更昂贵)?
this.myCopyOfData = sharedData.get(key).clone();
TIA。
(已对静态初始值设定项进行了编辑,以提供更多上下文。)