设计模式-单例模式

mac2022-06-30  19

设计模式-单例模式

       单例模式是23种设计模式中较为简单的设计模式,面试中也是经常被面试官问到。但要真正在实际开发中运用好单例设计模式并不简单。本文主要介绍5种单例:饿汉式,懒汉式,懒汉式(内部静态类),注册式(枚举单例,threadlocal型单例(容器式))。前两种只要知道单例模式的人都知道,应付面试能讲出后三种绝对可以给自己加分。

       本文不提供测试结果!

饿汉式  /** * @description:饿汉式 */ public class HungrySingleton { /** * final修饰,防止暴力反射破环单例 * * 缺点:由于使用static修饰,不管单列是否被调用,对象在初始化时就会被创建,浪费空间 */ private static final HungrySingleton hungrySingleton = new HungrySingleton(); private HungrySingleton() { } public static HungrySingleton getHungrySingleton() { return hungrySingleton; } /** * readResolve方法,防止序列化破坏单列 * readResolve方法在反序列化创建对象时会用到 */ private Object readResolve(){ return hungrySingleton; } }

 

懒汉式 **  * @description:懒汉式,双重检验锁,保证多线程下的线程安全  *  * 双重检验锁,两次判断(lazySingleton == null),避免多线程时出现线程安全问题  */ public class LazySingleton {     private static LazySingleton lazySingleton = null;     private LazySingleton() {}     public static LazySingleton getInstance() {         if (lazySingleton == null) {             synchronized(LazySingleton.class) {                 if (lazySingleton == null) {                     lazySingleton = new LazySingleton();                 }             }         }         return lazySingleton;     } } 懒汉式,内部静态类 /**  * @description:懒汉式,内部静态类  *  * 内部类LazyHolder中的逻辑 :  *【private  static final LazyInnerClassSingleton LAZY = new LazyInnerClassSingleton()】  * 需要等到外部方法getInstance()被调用时才会执行,并不会因为static修饰在初始化时就加载。  * 运用JVM底层运行逻辑,巧妙解决了线程安全问题  * 代码中没有使用synchronized修饰,性能最优  */ public class LazyInnerClassSingleton {     private LazyInnerClassSingleton() {         /**          * 防止暴力反射,破坏单列          */         if (LazyHolder.LAZY != null){             throw new RuntimeException("LazyHolder.LAZY 已被初始化");         }     }     public static final LazyInnerClassSingleton getInstance() {         return LazyHolder.LAZY;     }     private static class LazyHolder {         private  static final LazyInnerClassSingleton LAZY = new LazyInnerClassSingleton();     } } 注册式:枚举单例 **  * @description:枚举单例,注册试(枚举)  *  * 不存在序列化和反射破坏单例的情况  * JDK底层做了处理  */ public enum  EnumSingleton {     INSTANCE;     private Object data;     public Object getData() {         return data;     }     public void setData(Object data) {         this.data = data;     }     public static EnumSingleton getInstance() {         return INSTANCE;     } }

 

注册式:threadlocal型单例(容器式) /**  * @description:threadlocal型单例,注册试单例(容器试)  * 伪线程安全,即在同一个线程中安全,多个线程调用getInstance()得到的实例不同  * 可动态实现多数据源切换  */ public class ThreadLocalSingleton {     public ThreadLocalSingleton() {}     public static final ThreadLocal<ThreadLocalSingleton> threadLocal =             ThreadLocal.withInitial(() -> new ThreadLocalSingleton());     public static ThreadLocalSingleton getInstance() {         return threadLocal.get();     } }

 

最新回复(0)