设计模式之单例模式

随声附和 提交于 2020-03-25 17:09:02

单例模式类图是23种设计模式类图中最简单的,因为它的类图上只有一个类!

什么时候会用到单例模式呢?

有一些对象我们只需要一个,比如说:线程池(ThreadPool)、缓存(cache)、日志对象、充当打印机设备的驱动程序的对象等等,如果创造出多个实例,就会出现程序行为异常或者与结果不一致的现象。

如何创造出独一无二的对象实例呢?

我们都知道:如果我有一个类NewObject(),

我想创建这个类的对象,怎么做?--------new NewObject()就可以了;

是不是可以无限创建呢? --------如果它是公开类就可以;

如果它的构造函数是私有的呢?  -------那别的类就不可以实例化它了(调用不了它的构造函数);

那谁来实例化它呢?  --------只能它自己进行实例化了;

那我怎么使用它呢?  --------通过get方法暴露出来;

那么:

public class NewObject{
   //声明静态变量类
   private static NewObject newObject;
   //构造函数私有化
   private NewObject();
   //get方法暴露出去以便其他类调用
   public static NewObject getInstance(){
      //判断变量类是否已经实例化 
      //如果newObject引用为null,表示还没有创建实例,利用私有构造函数产生一个实例并赋值给静态变量;
      //如果我们不需要这个实例,不调用这个get方法,它就永远不会产生,这就叫“延迟实例化”(lazy loading)
      if(newObject == null) {
          newObject = new NewObject();
      }
      return newObject;
   }
}

这样懒汉式单例模式就完成了。

单例模式的几种类型

  • 懒汉式(线程不安全):这是最基础的实现方式什么时候需要,什么时候需要进行实例化,但是不支持多线程。
  • 懒汉式(线程安全):由于单例模式只有一个实例,假如我多个线程需要操作同一个对象,那么线程安全就十分重要了。

             在获取方法上加上锁synchronized保证线程安全。

public class NewObject{
   //声明静态变量类
   private static NewObject newObject;
   //构造函数私有化
   private NewObject();
   //get方法暴露出去以便其他类调用
   public static synchronized NewObject getInstance(){
      if(newObject == null) {
          newObject = new NewObject();
      }
      return newObject;
   }
}
  •  恶汉式:在JVM加载此类时立刻创建实例,JVM保证任何线程在访问静态实例化变量之前,一定先创建此实例。适用于在创建和运行方面的负担不太重

的时候。

public class NewObject{
   //声明并实例化静态变量类
   private static NewObject newObject = new NewObejct();
   //构造函数私有化
   private NewObject();
   //get方法暴露出去以便其他类调用
   public static NewObject getInstance(){
      return newObject;
   }
}
  • 双检锁(double-checked locking):采用双锁机制,安全且在多线程情况下能保持高性能。
public class NewObject{      //使用volatile关键字,保证一致性
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {      //第一次检查
    if (singleton == null) {          //对象加锁
        synchronized (Singleton.class) {          //第二次检查,防止第一次检查之后其他线程创建实例
        if (singleton == null) {  
            singleton = new Singleton();  
        }  
        }  
    }  
    return singleton;  
    }  
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!