单线设计模式与线程安全

时间:2014-04-27 15:30:24

标签: singleton

我读了同步新实例创建的原因是两个线程可以同时访问getInstance并发现_instance为null并创建了Singleton类的两个实例。所以为了消除我们同步它。但是,为什么再次引入双重检查的锁定方法,检查同步块内的实例是否为空。这有必要吗?一旦代码块被同步,它已经线程安全了吗?

public class Singleton {
        private static Singleton _instance = null;

        private Singleton() {   }

        public static Singleton getInstance() {
                if (_instance == null) {
                      synchronized (Singleton.class) {
                          _instance = new Singleton(); // why need to again check null
                      }
                }
                return _instance;
        }
} 

1 个答案:

答案 0 :(得分:0)

synchronized块将按顺序执行(即一次一个线程),但这还不够,因为对_instance = new Singleton()的第二次调用可能会覆盖第一次。

如果在第一个线程评估_instance == null表达式后立即发生一个上下文切换,并且在另一个线程评估_instance == null表达式之前不会发生其他上下文切换,那么这是一个合理的场景。

因此,一旦进入synchronized块,当前线程必须确保_instance仍为null,然后再将其设置为new Singleton()