Double-Checked Locking Pattern(双重检查锁定模式)经常被用于 Singleton 模型中实现 lazy load。
public static Singleton getInstance(){
if (instance == null){
synchronized(Singleton.class) { //1
if (instance == null) //2
instance = new Singleton(); //3
}
}
return instance;
}
问题的起因在于语言 3,JIT 所生成的汇编代码实现如下。
1. 先申请一块空内存
2. 将其地址赋予 instance
3. 在 instance 所指的地址之上构建对象
如果线程调度发生在 instance 已经被赋予一个内存地址,而 Singleton 的构造函数还没有被调用的微妙时刻。
那么另一个进入此函数的线程 b 会发觉 instance 已经不为 null,从而返回 instance 并使用。但是这个时候线程 b 并不知道此时 instance 还没有被初始化。
在 JDK1.5 或者更晚的版本中,扩展了 volatile 的语义,使得我们可以通过将 helper 属性字段设置为 volatile 来修复 Double-Checked 的问题。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于