我有以下代码:
class SomeClass {
private Map<String, String> someMap = null;
public String getValue(String key) {
if (someMap == null) {
someMap = initialize(); // initialize() is some method which returns a proper map.
}
return someMap.get(key);
}
}
假设我不关心someMap
多次初始化,是否还有其他线程安全问题需要我关注。
根据what-operations-in-java-are-considered-atomic,参考分配肯定是atmoic。 someMap
的赋值是否在方法调用initialize()
后保证发生(对我而言似乎合乎逻辑)。线程是否有可能看到部分构造的someMap
。如果不是地图,我有其他类型的对象。
答案 0 :(得分:4)
代码不是线程安全的。如果两个线程在同一个对象上调用方法getValue
,则有可能一个线程看到部分创建的someMap
。
为了避免此问题,您必须删除数据争用。最简单的解决方案是将someMap
声明为volatile
。要记住的简单规则是:如果代码不包含数据竞争,那么所有执行都将显示为顺序一致。
答案 1 :(得分:0)
即使你输入volatile也不是线程安全,因为如果两个线程同时被调用getValue方法,可能会发生以下情况
1)主题1&amp;线程2 检查 if(someMap == null),两者都会通过并尝试重新初始化。
2)两者都将重新初始化参考。线程1返回旧引用,哪一个被线程2覆盖。
3)因此,请参阅链接Double Checked Locking in Singleton