为什么我们需要在获取锁之前和之后检查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 检查
instance == null
并发现此条件为真。 - 线程 2 检查
instance == null
并发现此条件为真。 - 线程 1 获取锁。
- 线程 2 尝试获取锁,它已经获取,因此线程 2 等待。
- 线程 1 初始化
instance = new DclSingleton()
。 - 线程 1 释放锁。
- 线程 2 获取锁。
- 线程 2 初始化
instance = new DclSingleton()
。 我们有双重初始化。
关于java - 为什么在Java中设计单例模式时需要双重检查锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54780284/