这个代码Double Checked Locking安全吗?

Ais*_*war 2 java concurrency multithreading double-checked-locking

我正在查看我们的应用程序中的一些代码,我认为可能会遇到" 双重检查锁定 "的情况.我写了一些与我们的工作类似的示例代码.

任何人都可以看到这是如何经历双重检查锁定?或者这样安全吗?

class Foo {
    private Helper helper = null;
    public Helper getHelper() {
        Helper result;
        synchronized(this) {
            result = helper;
        }

        if (helper == null) {
            synchronized(this) {
                if (helper == null) {
                    helper = new Helper();
                }
            }
        }
        return helper;
    }
}
Run Code Online (Sandbox Code Playgroud)

wiki借来的基本代码.

Ric*_*lly 6

这是不必要的复杂,最简单的"安全"做DCL的方式是这样的:

class Foo {
  private volatile Helper helper = null;
  private final Object mutex = new Object(); 
  public Helper getHelper() {
    if (helper == null) {
        synchronized(mutex) {
            if (helper == null) {
                helper = new Helper();
            }
        }
    }
    return helper;
  }
}
Run Code Online (Sandbox Code Playgroud)

这里的关键点是:

  • 在'happy'的情况下,我们希望已经分配了helper,所以如果是,我们可以返回它而不必输入synchronized块.
  • Helper被标记为volatile,让编译器知道任何线程都可以随时读取/写入助手,重要的是读/写不会被重新排序.
  • synchronized块使用私有final变量进行同步,以避免在实例上另一个代码区域同步时出现潜在的性能损失this.

  • 您应该将助手分配给局部变量. (2认同)