设计模式之单例模式

什么是单例模式

  单例模式,是一种常用的软件设计模式。

  在它的核心结构中只包含一个被称为单例的特殊类。

  通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。

单例模式分别有懒汉模式饿汉模式

懒汉模式:

public class Lazy {
  //将构造方法私有化,不循序外部直接创建对象
  private Lazy(){
  }
  //2.声明类的唯一实例
  private static Lazy instance;
  //3.提供一个用于获取实例的方法
  public static synchronized Lazy getInstance(){ //加同步锁
    if(instance == null){
       instance = new Lazy();
  }
       return instance;  
  }
}

注:为何称他为懒汉呢?我们可以把他当成一个酒店员工,因为他比较懒,所以每次都要等客人来就餐的时候(Lazy.getInstance()),他才开始去生产,instance = new Lazy()

饿汉模式:

public class Starving {
  //1.将构造方法私有化,不允许外部直接创建对象
  private Starving() {
  }

  //2.创建类的唯一实例
  private static Starving instance = new Starving();

  //提供一个用于获取实例的方法
  //需要注意的是,我们这个方法属于对象,不是类方法
  //public Starving getInstance() {
  //return instance;
  //}

  //3.提供一个用于获取实例的私有的类的静态成员方法
  public static Starving getInstance() {
       return instance;
  }
}

注:为何称他为饿汉呢?可以想象成一个饭点时间,就餐时间还没到(Starving.getInstance),饿汉就已经准备好菜啦(private static Starving instance = new Starving()),一到时间马上吃饭,不用再等待上菜。

双重锁的形式:

public class Singleton {
    private static volatile Singleton instance=null;
    private Singleton() {
        //do something
    }
    public static  Singleton getInstance( ) {
        //这个模式将同步内容下方到if内部,提高了执行的效率,
     //不必每次获取对象时都进行同步,只有第一次才同步,创建了以后就没必要了。
        if (instance == null) {
            synchronized(Singleton.class){
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
     }
}  

注:这种模式中双重判断加同步的方式,比第一个例子中的效率大大提升,因为如果单层if判断,在服务器允许的情况下,假设有一百个线程,耗费的时间为100*(同步判断时间+if判断时间),而如果双重if判断,100的线程可以同时if判断,理论消耗的时间只有一个if判断的时间。所以如果面对高并发的情况,而且采用的是懒汉模式,最好的选择就是双重判断加同步的方式。

总结与区别:

饿汉模式的特点是加载类时比较慢,但运行时获取对象的速度比较快,线程安全。

饿汉模式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变。

懒汉模式的特点是加载类时比较快,但是在运行时获取对象的速度比较慢,线程不安全。

懒汉模式如果在创建实例对象时不加上synchronized则会导致对象的访问不是线程安全的。

所以在此推荐大家使用饿汉模式

原文地址:https://www.cnblogs.com/sanjun/p/7890470.html