谁能告诉我这个类是否是线程安全的?
class Foo {
private final Map<String,String> aMap;
public Foo() {
aMap = new HashMap<String, String>();
aMap.put("1", "a");
aMap.put("2", "b");
aMap.put("3", "c");
}
public String get(String key) {
return aMap.get(key);
}
}
编辑:我没有澄清问题是我的错。根据JMM FAQ :
A new guarantee of initialization safety should be provided. If an object is properly constructed (which means that references to it do not escape during construction), then all threads which see a reference to that object will also see the values for its final fields that were set in the constructor, without the need for synchronization.
这让我感到困惑,因为 aMap 的集合是 aMap = new HashMap<String, String>();
.这样其他线程就可以看到这些
aMap.put("1", "a");
aMap.put("2", "b");
aMap.put("3", "c");
还是不是?
编辑:我找到了这个 question这完全符合我的问题
最佳答案
正如已经指出的那样,它绝对是线程安全的,final
在这里很重要,因为它具有内存可见性效果。
final
的存在保证其他线程在构造函数完成后可以在映射中看到值,而无需任何外部同步。如果没有 final
,就不能在所有情况下都得到保证,并且在使新构造的对象对其他线程可用时,您需要使用安全发布习语,即(来自 Java Concurrency in Practice ) :
- Initializing an object reference from a static initializer;
- Storing a reference to it into a volatile field or AtomicReference;
- Storing a reference to it into a final field of a properly constructed object; or
- Storing a reference to it into a field that is properly guarded by a lock.
关于Java 并发数 : is final field (initialized in constructor) thread-safe?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6457109/