单例模式类图是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; } }
来源:https://www.cnblogs.com/wulachen/p/12566629.html