单例模式有一种 双重检验锁的写法,其中 volatile 用来保证 Jit 编译器进行指令重排,以防其他线程获取了未初始化的实例。
我的问题是:synchronized 关键字不是可以保证线程的可见性、原子性和有序性吗?不是在执行完同步代码释放锁之前将工作内存的值同步刷新到主内存中吗?如果是这样那么其他线程在 2 次检测的时候不应该都是拿到的是非 null 的且已经初始化的实例吗?为什么还会有这种情况呢?
怀疑的方向: 难道说 synchronized 在释放锁之前就已经会把工作内存的一些值同步到主内存?那同步还有啥意义呢。
public class Singleton {
private volatile static Singleton uniqueInstance;
private Singleton() {}
public static Singleton getUniqueInstance() {
//先判断对象是否已经实例过,没有实例化过才进入加锁代码
if (uniqueInstance == null) {
//类对象加锁
synchronized (Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.