场景
设计模式-单例模式-饿汉式单例模式、懒汉式单例模式、静态内部类在Java中的使用示例:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/127555096
上面讲了单例模式的三种方式,另外还有一种注册式单例模式。
注册式单例模式
注册式单例模式又称为登记式单例模式,就是将每一个示例都登记到某个地方,使用唯一的标识获取实例。
注册式单例模式又两种:一种是枚举式单例模式,另一种为容器式单例模式。
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。
实现
枚举式单例模式
创建EnumSingleton类
package com.ruoyi.demo.designPattern.enumSingleton; /** * 枚举式单例模式 */ 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; } }
创建测试代码
package com.ruoyi.demo.designPattern.enumSingleton; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class EnumSingletonTest { public static void main(String[] args) { try{ EnumSingleTon instance1 = null; EnumSingleTon instance2 = EnumSingleTon.getInstance(); instance2.setData(new Object()); FileOutputStream fos = new FileOutputStream("EnumSingleton.obj"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(instance2); oos.flush(); oos.close(); FileInputStream fis = new FileInputStream("EnumSingleton.obj"); ObjectInputStream ois = new ObjectInputStream(fis); instance1 = (EnumSingleTon) ois.readObject(); ois.close(); System.out.println(instance1.getData()); System.out.println(instance2.getData()); System.out.println(instance1.getData() == instance2.getData()); }catch (Exception e){ e.printStackTrace(); } } }
运行结果如下
为什么用这个序列化测试,因为序列化会破坏其他方式的单例模式效果。
设计模式-静态内部类方式被反射破坏和饿汉式单例模式被序列化破坏解决方式:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/127568127
容器式单例模式
注册式单例模式的另一种写法,容器式单例模式,新建ContainerSingleton类
package com.ruoyi.demo.designPattern.containerSingleton; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * 容器式单例模式 */ public class ContainerSingleton { private ContainerSingleton(){} private static Map<String,Object> ioc = new ConcurrentHashMap<>(); public static Object getBean(String className){ synchronized (ioc){ if(!ioc.containsKey(className)){ Object obj = null; try{ obj = Class.forName(className).newInstance(); ioc.put(className,obj); }catch (Exception e){ e.printStackTrace(); } return obj; }else { return ioc.get(className); } } } }
容器式单例模式适用于实例很多的情况,便于管理,但它是非线程安全的。