具有同步块的Java内存模型中Singleton的弱点

时间:2015-03-21 19:37:41

标签: java multithreading singleton data-synchronization java-memory-model

我正在阅读Nir Shavit的“多处理器计算的艺术”。它解释了Java Memory Model并在第62页给出了一个例子:

public static Singleton getInstance() {
  if (instance == null) {
    synchronized(Singleton.class) {
      if (instance == null)
      instance = new Singleton();
    }
  }
  return instance;
}

并说:

  

此模式一旦出现,就是不正确的。在第5行,构造函数   调用似乎在分配实例字段之前发生,但是   Java内存模型允许这些步骤不按顺序发生,   有效地使部分初始化的Singleton对象可见   其他节目。

那么,这是否意味着这种同步可能无法保证我们对Singleton的要求?

1 个答案:

答案 0 :(得分:1)

  

那么,这是否意味着这种同步可能无法保证   我们想从Singleton那里得到什么?

这取决于你想要的单身人士。如果您只想要一个实例,则代码段中的解决方案将实现该目标。如果你只想要一个实例,并且你想要在访问它时完美地初始化该实例(那要求太多了吗?),那么,不,你将无法通过代码片实现这一点。

另一个线程调用getInstance并读取instance字段的值

if (instance == null) {

可能会看到一个指定值,该值引用了尚未由控制器初始化的对象。由于该值不是null,因此该方法返回它并且未初始化的对象泄漏。

通过将字段标记为volatile来修复此问题。