免责声明:我不在实际的生产代码中使用DCL-我只是出于学术兴趣。

我读过以下著名的文章:The "Double-Checked Locking is Broken" Declaration

问题声明(我的看法):

// Correct multithreaded version
class Foo {
  private Helper helper = null;
  public synchronized Helper getHelper() {
    if (helper == null)
        helper = new Helper();
    return helper;
    }
  // other functions and members...
  }


假设thread_1执行了helper = new Helper();
   另一个Thread(thread_2might看到helper链接不为空,但尚未初始化。发生这种情况是因为构造函数调用可能会使用helper链接分配进行重新排序
来自thread_2 veiw。

但是在本文中提到,这种方法适用于32位基元。


  尽管双重检查锁定习惯用法不能用于
  引用对象,它可以用于32位原始值(例如,
  整数或浮点数)。请注意,它不适用于长整数或双精度数,
  因为不同步对64位原语的读取/写入不是
  保证是原子的。


// Correct Double-Checked Locking for 32-bit primitives
class Foo {
  private int cachedHashCode = 0;
  public int hashCode() {
    int h = cachedHashCode;
    if (h == 0)
    synchronized(this) {
      if (cachedHashCode != 0) return cachedHashCode;
      h = computeHashCode();
      cachedHashCode = h;
      }
    return h;
    }
  // other functions and members...
  }


请解释一下它为什么起作用?我知道32位写入是原子的。

这里局部变量的原因是什么?

最佳答案

“ DCL已损坏”的概念是,使用DCL初始化单例对象,线程可以在看到对象处于完全初始化状态之前看到对该对象的引用。 DCL充分同步了引用单例的有效最终全局变量,但无法同步全局引用的单例对象。

在您的示例中,只有全局变量。没有“它所指的对象”。

09-25 21:44