java - 为什么在Java中设计单例模式时需要双重检查锁?

标签 java design-patterns synchronization singleton

为什么我们需要在获取锁之前和之后检查null? 一旦我们获得了锁,没有线程可以拥有锁那么为什么不在同步块(synchronized block)之前进行空检查?

public class DclSingleton {
    private static volatile DclSingleton instance;
    public static DclSingleton getInstance() {
        **if (instance == null) {**
            synchronized (DclSingleton .class) {
                **if (instance == null) {**
                    instance = new DclSingleton();
                }
            }
        }
        return instance;
    }

    // private constructor and other methods...
}

最佳答案

想象下一个场景:

  1. 线程 1 检查 instance == null 并发现此条件为真。
  2. 线程 2 检查 instance == null 并发现此条件为真。
  3. 线程 1 获取锁。
  4. 线程 2 尝试获取锁,它已经获取,因此线程 2 等待。
  5. 线程 1 初始化 instance = new DclSingleton()
  6. 线程 1 释放锁。
  7. 线程 2 获取锁。
  8. 线程 2 初始化 instance = new DclSingleton()我们有双重初始化

关于java - 为什么在Java中设计单例模式时需要双重检查锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54780284/

相关文章:

linux - 如何从 Linux 上的文件夹同步最后修改的文件

java - 如何避免代码重复?

java - 如何分离与@SpringBootApplication注释的类不同的类中的bean

java - 如何使用 Mockito 模拟方法调用链

java - 使用数组和可变长度形式参数。 (java :38: error: '.class' expected)

java - 这是装饰器设计模式的一个很好的例子吗?

c++ - 如何最好地让用户重新定义类方法?

Java线程同步对象的等待和通知

file - 即时将文件从Windows镜像/同步到Linux服务器的最佳方法

java - Spring 和 XSLT,字符编码