繁体   English   中英

这个代码Double Checked Locking安全吗?

[英]Is this code Double Checked Locking safe?

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

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

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;
    }
}

wiki借来的基本代码。

这是不必要的复杂,最简单的“安全”做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;
  }
}

这里的关键点是:

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

双重检查锁定的重点是快速路径(当您不需要实例化对象时)不同步。 所以你所拥有的不是双重锁定。

你需要摆脱第一个同步块,以获得一个破坏的双重检查锁。 然后你需要helper volatile来修复它。

这部分是标准的双重检查锁定:

if (helper == null) {
    synchronized(this) {
        if (helper == null) {
            helper = new Helper();
        }
    }
}

第一部分是无用的赋值,它对双重检查的锁定部分没有任何作用:如果helper为null则无论如何都会执行,如果不是,则无论如何都不会执行。 它完全无效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM