单例模式

来源:互联网 发布:windows 调试 safari 编辑:程序博客网 时间:2024/06/06 01:38

第一种

public class Singleton {    //一个静态的实例      private static Singleton singleton=null;     //私有化构造函数      private Singleton(){}     //给出一个公共的静态方法返回一个单一实例     public static Singleton newInstance(){        if (singleton==null) {            singleton=new Singleton();        }        return singleton;    }}

这是在不考虑并发访问的情况下标准的单例模式的构造方式,当并发访问的时候,第一个调用newInstance方法的线程A,在判断完singleton是null的时候,线程A就进入了if块准备创造实例,但是同时另外一个线程B在线程A还未创造出实例之前,就又进行了singleton是否为null的判断,这时singleton依然为null,所以线程B也会进入if块去创造实例,这时问题就出来了,有两个线程都进入了if块去创造实例,结果就造成单例模式并非单例。

第二种

public class BadSynchronizedSingleton {      //一个静态的实例      private static BadSynchronizedSingleton synchronizedSingleton;      //私有化构造函数      private BadSynchronizedSingleton(){}     //给出一个公共的静态方法返回一个单一实例      public synchronized static BadSynchronizedSingleton newInstance(){          if (synchronizedSingleton == null) {              synchronizedSingleton = new BadSynchronizedSingleton();          }          return synchronizedSingleton;      }  }

上面的做法很简单,就是将整个获取实例的方法同步,这样在一个线程访问这个方法时,其它所有的线程都要处于挂起等待状态,倒是避免了刚才同步访问创造出多个实例的危险,但是我只想说,这样的设计实在是糟糕透了这样会造成很多无谓的等待。

第三种

    //一个静态的实例      private static SynchronizedSingleton synchronizedSingleton;      //私有化构造函数      private SynchronizedSingleton(){}      //给出一个公共的静态方法返回一个单一实例      public static SynchronizedSingleton getInstance(){          if (synchronizedSingleton == null) {              synchronized (SynchronizedSingleton.class){                if(synchronizedSingleton==null){                    synchronizedSingleton=new SynchronizedSingleton();                }            }        }          return synchronizedSingleton;      }  

这种做法与上面那种最无脑的同步做法相比就要好很多了,因为我们只是在当前实例为null,也就是实例还未创建时才进行同步,否则就直接返回,这样就节省了很多无谓的线程等待时间

第四种

public class InnerClassSingleton {    public static Singleton getInstance() {        return Singleton.singleton;    }    private static class Singleton {        protected static Singleton singleton = new Singleton();    }}

上面这种这样不太符合我们的习惯。所以我们改为以下形式

public class Singleton2 {    private Singleton2(){}      public static Singleton2 getInstance(){          return SingletonInstance.instance;      }      private static class SingletonInstance{          static Singleton2 instance = new Singleton2();      }  }

建议使用上面这种

第五种
俗称饿汉式加载。

public class Singleton3 {      private static Singleton3 singleton = new Singleton3();          private Singleton3(){}          public static Singleton3 getInstance(){              return singleton;          }  }

不建议使用

原创粉丝点击