java - 为什么要使用双重检查锁定

标签 java double-checked-locking

关于 previous question我提出,

    public static Singleton getInstanceDC() {
    if (_instance == null) {                // Single Checked (1)
        synchronized (Singleton.class) {
            if (_instance == null) {        // Double checked (2)
                _instance = new Singleton();
            }
        }
    }
    return _instance;

为什么要使用第二个实例空检查条件。它可能产生什么影响?

最佳答案

让我们对行进行编号,以便了解线程如何交错操作。

if (_instance == null) {                // L1
    synchronized (Singleton.class) {    // L2
        if (_instance == null) {        // L3
            _instance = new Singleton();// L4
        }
    }
}

让我们考虑一个不检查 L3 的交错。

  1. 线程 1 到达 L1 且 _instancenull
  2. 线程 2 到达 L1 且 _instancenull
  3. 线程 1 在 L2 获得互斥锁
  4. 线程 2 试图在 L2 处获取互斥量但阻塞了
  5. 线程 1 创建新实例并在 L4 分配
  6. 线程 1 从 L2 释放互斥锁
  7. 线程 2 在 L2 获得互斥锁
  8. 线程 2 创建新实例并在 L4 分配
  9. 线程 2 从 L2 释放互斥量

Singleton 创建了两个实例。每个线程返回自己的实例。

通过 L3 的检查,第 8 步不会发生,因为在第 7 步线程 2 的 _instance View 与线程 1 的 View 同步,因此只有一个 Singleton 实例已创建。

关于java - 为什么要使用双重检查锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33427986/

相关文章:

java - 带继承的 Junit 测试是好是坏?讨论

java - FQL 查询在接下来的 30 天内使用 Android 获取 Facebook friend 的生日

java - Java 中没有同步的线程安全单例?

java - 使用 Java 从 URL 截断域

java - 使用 m2e 的生命周期配置未涵盖插件执行

java - 为什么在单例类的情况下双重检查锁定不会像这样失败?

java - volatile 读取冲突

java - 在使用双锁时使单例实例易失有什么意义?

java - 如何使 ArrayList 在 java 中用作二维数组?

c++ - 解释双重检查锁定中的竞争条件