美文网首页
单例模式纠错

单例模式纠错

作者: shiyuzhe | 来源:发表于2018-09-18 11:23 被阅读20次

    忽然发现之前写的单例有问题,如下:

    public class Singleton{

    private static Singleton instance = null ;

    private Singleton() {}

    public static Singleton getInstance() {  

        if (instance == null) {  

             synchronized (instance) {

                if(instance == null){

                     instance =new Singleton();

                } } }  

        return instance;  

    }  }

    首先说说同步,synchronized 加在了内部,对性能会有一定提升。当调用的时候是不需要加锁的,只有在instance为null,并创建对象的时候才需要加锁。

    开篇说的有问题是在多线程中这样写可能拿到未初始化的instance。why?

    我们以A和B两个线程为例,当A和B同时进入第一个if判断时:

    A首先进入synchronized块,由于instance为null,所以它执行instance = new Singleton();

    因为instance = new Singleton()分两步执行,但不保证执行的先后顺序。有可能JVM会为新的Singleton实例分配空间,然后直接赋值给instance成员,然后再去初始化这个Singleton实例。

    如果A在没有开始初始化这个实例时离开同步块,此时instance不空,但未初始化。

    B在这个时候进入synchronized块,instance不空,会直接返回未初始化的instance。

    怎么解决:

    方案1:分离开创建的过程,给创建过程加同步锁。

    public class Singleton{

    private static Singleton instance = null ;

    private Singleton() {}

    public static Singleton getInstance() {  

        if (instance == null) {  initInstance(); }  

        return instance;  

    private static synchronized void initInstance() {

        if(instance == null){

            instance =new Singleton();

        }} 

    }

    方案2:使用内部类来维护单例的实现

    public class Singleton{

    private Singleton() {}

    public static     getInstance() { return SingletonFactory.instance;  } 

    private static class SingletonFactory {  private static Singleton instance = new Singleton();  }  

    }

    相关文章

      网友评论

          本文标题:单例模式纠错

          本文链接:https://www.haomeiwen.com/subject/bljynftx.html