设计模式之单例模式
学习编程学习到一定程度不可避免的需要去学习更深层次的东西,虽然在之前的学习中接触到一些设计模式,但是自己没有能够好好总结,以至于没能体会到更高深的编程乐趣。
单例模式要点为以下几点
1.单例类不可继承
2.私有化构造函数
3.公开静态化实例获取方法
一,首先是最熟悉的简单的单例模式
package V1; //最简单的单例设计模式 public final class Singleton { //静态成员变量 private static Singleton instance =null; //私有化构造函数 private Singleton(){ } //公开 静态化 实例获取方法 public static Singleton getInstance(){ if(instance ==null){ instance =new Singleton(); } return instance; } }
线程安全:非线程安全
类型:简单单例模式
是否Lazy初始化:是
二.其次是简单的线程安全单例模式
//类不可继承 public final class Singleton { //私有化静态成员变量 private static Singleton instance =null; //私有化构造函数 private Singleton(){ } //公开静态方法 懒汉模式 同步方法 public static synchronized Singleton getInstance(){ if(instance==null){ instance =new Singleton(); } return instance; } }
相对于第一种模式,这个单例模式采取synchronized关键字,获取方法为线程安全方法,
线程安全:线程安全
类型:懒汉模式的单例
是否Lazy初始化:是
对于类型的其他实现
package V2; //考虑线程安全的单例模式 public final class Singleton { //私有化静态成员变量 private static Singleton instance=null; //线程锁对象 private static final Object queuelock =new Object(); //私有化构造函数 private Singleton(){ } //静态化实例获取 public static Singleton getInstance(){ //悲观锁 也是俗称的懒汉模式 即认为第一次出现的可能性较高 synchronized(queuelock){ if(instance==null){ instance =new Singleton(); } } return instance; } }
想较于第上面那种实现,唯一的改变为该锁方法为锁区域,但是实际上仍然是一种懒汉模式
线程安全:线程安全
类型:懒汉模式的单例
是否Lazy初始化:是
三.双重校验模式
package V3; //final 不可继承 public final class Singleton { //静态私有化成员变量 private static Singleton instance =null; //创立锁对象 private static Object queueLock =new Object(); private Singleton(){ } //公有化 静态方法 实例获得方法 public static Singleton getInstance(){ //乐观锁 出现为null 情况较少 if(instance==null){ synchronized (queueLock){ //为什么里面这层不能够去掉 是因为在同步代码块中的才是线程安全 //synchronized之前的if语句主要是为了 减少等待 if(instance == null) { instance =new Singleton(); } } } return instance; } }
相较于第二种模式,第三种模式更侧重于校验单例是否实例化
线程安全:线程安全
类型:双重锁的单例
是否Lazy初始化:是
四.静态初始化的单例模式
package V4; //类不可继承 饿汉模式 依赖于类加载器加载 //确定 对于内存的消耗 容易产生较多需要销毁的对象 但是依然是线程安全 //静态初始化 public final class Singleton { //私有化静态成员变量 private static Singleton instance =new Singleton(); //私有化类构造函数 private Singleton(){ } //公开静态实例的获取方法 public static Singleton getInstance(){ return instance; } }
相较于其他的单例模式,这种单例模式更依赖于ClassLoader,在类初始化时调用,生成实例对象,但是比较容易产生较多的可回收对象,对于内存的消耗可能较多
线程安全:线程安全
类型:静态初始化的单例
是否Lazy初始化:否
五:延迟加载的单例模式
package V6; //类不可继承 继承有可能破坏对象的封装 //单例模式 延迟加载 //即是线程安全 有是能够解决多数单例问题的最佳方案 public final class Singleton { private Singleton(){ } public static Singleton getInstance(){ return Nested.instance; } private static class Nested{ public static Singleton instance =new Singleton(); } }
相较于其他的单例实现方法,这种单例的实现方法更为依赖内部类,延迟加载,是大多数大规模框架中常见的单例模式,也是最受喜爱的单例模式
线程安全:线程安全
类型:延迟加载的单例
是否Lazy初始化:是
恐惧源于无知,代码改变世界