当前位置: 首页 > news >正文

spring设计模式-单例模式

单例模式

:是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点。单例模式是创建型模式

  • 懒汉式单例模式:在类加载的时候就立即初始化,并且创建为单例对象,它绝对线程安全,线程还没出现的时候就实例化了
  • 不可能存在访问安全问题。
  • 优点:没有加任何锁,执行效率比较高,用户体验比懒汉式单例模式更好
  • 缺点:类加载的时候就初始化,不管用不用都占着空间,浪费了内存。
饿汉式: public class HungrySingleton { private static HungrySingleton hungrySingleton=new HungrySingleton(); //另一种写法 private static HungrySingleton hungrySingleton1; static{ hungrySingleton1=new HungrySingleton(); } private HungrySingleton(){} public static HungrySingleton getInstance(){ return hungrySingleton; } } 懒汉式: /** * 特点:被外部类调用的时候,内部类才会被加载.缺点:线程不安全 */ public class LazySingleton { private LazySingleton(){} private static LazySingleton lazySingleton=null; public static LazySingleton getInstance(){ if (lazySingleton==null){ lazySingleton=new LazySingleton(); } return lazySingleton; } //方法一:线程不安全的办法,加锁,缺点:性能下降 public static synchronized LazySingleton getInstance1(){ if (lazySingleton==null){ lazySingleton=new LazySingleton(); } return lazySingleton; } //方法二:双重检验所:解决线程安全和性能问题(双重检验锁) public static LazySingleton getInstance2(){ if(lazySingleton==null){ synchronized (LazySingleton.class){ if(lazySingleton==null){ lazySingleton=new LazySingleton(); //1、分配内存给这个对象 //2、初始化对象 //3、设置lazysingleton指向刚分配的内存地址 } } } return lazySingleton; } } 内部类: package com.wanda.singleton; import java.lang.reflect.Constructor; /** * 这种形式兼顾了饿汉式内存浪费问题和synchronized性能问题 */ public class LazyInnerSingleton { // private LazyInnerSingleton(){} //修改后的构造方法 private LazyInnerSingleton(){ if(LazyHolder.lazy!=null){ throw new RuntimeException("不允许创建多个实例"); } } public static final LazyInnerSingleton getInstance(){ return LazyHolder.lazy; } //内部类在方法调用之前初始化,避免了线程不安全的问题 private static class LazyHolder{ private static final LazyInnerSingleton lazy=new LazyInnerSingleton(); } public static void main(String[] args) { //反射破坏单例情况,通过这种方式会创建两个不同的单例。可以在构造方法中做一些限制,一旦多次重复创建就抛出异常。 try { Class<?> clazz=LazyInnerSingleton.class; Constructor constructor=clazz.getDeclaredConstructor(null); //强制访问 constructor.setAccessible(true); Object o1=constructor.newInstance(); Object o2=constructor.newInstance(); System.out.println(o1==o2); }catch (Exception e){ e.printStackTrace(); } } } 序列化破坏单例 package com.wanda.singleton; import java.io.*; //一个单例对象创建后,有时需要序列化到磁盘,下次使用时在从磁盘读入,进行反序列化,反序列华的对象会重新分配内存 //即重新创建,如果序列化的对象是单例,就违背了单例的意义。 public class SeriableSingleton implements Serializable { public static final SeriableSingleton INSTANCE=new SeriableSingleton(); private SeriableSingleton(){} public static SeriableSingleton getInstance(){ return INSTANCE; } private Object readResolve(){ return INSTANCE; } public static void main(String[] args) { SeriableSingleton s1=null; SeriableSingleton s2=SeriableSingleton.getInstance(); FileOutputStream fos=null; try { fos=new FileOutputStream("seriablesingleton.obj"); ObjectOutputStream os=new ObjectOutputStream(fos); os.writeObject(s2); os.flush(); os.close(); FileInputStream fis=new FileInputStream("seriablesingleton.obj"); ObjectInputStream ois=new ObjectInputStream(fis); s1=(SeriableSingleton) ois.readObject(); ois.close(); System.out.println(s1); System.out.println(s2); System.out.println(s1==s2);//false 解决方法:加上readResolve方法 }catch (Exception e){ } } } 枚举: package com.wanda.singleton; import java.io.*; //一个单例对象创建后,有时需要序列化到磁盘,下次使用时在从磁盘读入,进行反序列化,反序列华的对象会重新分配内存 //即重新创建,如果序列化的对象是单例,就违背了单例的意义。 public class SeriableSingleton implements Serializable { public static final SeriableSingleton INSTANCE=new SeriableSingleton(); private SeriableSingleton(){} public static SeriableSingleton getInstance(){ return INSTANCE; } private Object readResolve(){ return INSTANCE; } public static void main(String[] args) { SeriableSingleton s1=null; SeriableSingleton s2=SeriableSingleton.getInstance(); FileOutputStream fos=null; try { fos=new FileOutputStream("seriablesingleton.obj"); ObjectOutputStream os=new ObjectOutputStream(fos); os.writeObject(s2); os.flush(); os.close(); FileInputStream fis=new FileInputStream("seriablesingleton.obj"); ObjectInputStream ois=new ObjectInputStream(fis); s1=(SeriableSingleton) ois.readObject(); ois.close(); System.out.println(s1); System.out.println(s2); System.out.println(s1==s2);//false 解决方法:加上readResolve方法 }catch (Exception e){ } } } 容器式: package com.wanda.singleton; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * 容器式单例模式:非线程安全 */ public class ContainerSingleton { private ContainerSingleton(){} private static Map<String,Object> map=new ConcurrentHashMap<>(); public static Object getBean(String clazzName){ synchronized (map){ if(!map.containsKey(clazzName)){ Object obj=null; try{ obj=Class.forName(clazzName).newInstance(); map.put(clazzName,obj); }catch (Exception e){ e.printStackTrace(); } return obj; }else{ return map.get(clazzName); } } } }
http://www.jsqmd.com/news/1281374/

相关文章:

  • 5个ClosedXML实战技巧:轻松玩转.NET Excel自动化
  • TPIC7710EVM评估模块实战指南:硬件解析与GUI软件高效调试
  • 韶关工厂设备打包回收:厂房电缆拆除+中央空调回收+变压器回收一站式处置推荐 - 广东再生资源回收
  • C 排序算法:快速排序
  • 2026贵阳白云区黄金回收避坑攻略|本地正规门店免费上门,无套路高价收金 - 得天独厚
  • Map 随堂笔记
  • .NET 8配置系统与Serilog日志集成实战指南
  • 2026沈阳和平/沈河/铁西/大东/于洪/浑南/苏家屯/沈北防水堵漏排行榜|屋顶外墙防水、厨卫免砸砖、地下室堵漏、窗台阳台渗水、厂房商铺屋面翻新三家差异化靠谱服务商推荐 - 信息热点
  • 终极指南:使用UsbDk在Windows上实现USB设备直接访问开发
  • 计算机毕业设计之基于springboot的个人提升系统的设计与实现
  • 物料凭证、检验批
  • fink 操作
  • Visual C++运行库一键修复:告别DLL错误,5分钟解决Windows软件兼容性问题终极指南
  • 山东栋梁集团 —— 济南中德栋梁工业具身智能机器人训练场
  • MMC-VSC-HVDC系统MATLAB建模与仿真实践
  • 2026 济源黄金回收避坑指南|全城上门 + 实体门店透明变现,本地套路全拆解 - GrowUME
  • MATLAB实现IEEE 33节点配电网最优重构方案
  • 基于Arduino的宠物机器人制作:从硬件选型到行为编程全解析
  • 2026无锡黄金回收实测:禹竞名奢汇等5家店成透明新 - 商业每日快报
  • 小熊猫Dev-C++:为什么这个轻量级IDE是C++新手的完美起点?
  • 2026.7月庐阳防水补漏指南:科学修缮告别年年修年年漏 - 超人防水
  • 物联网硬件选型与LTE Cat 1通信模块应用解析
  • 2026优选扬州邗江区至广州物流企业排行参考 - 起跑123
  • 2026 年武汉机械设备出租土石方工程,自建房挖基础租赁要点 - LYL仔仔
  • JackSon jar包下载
  • 抖音下载神器:三步搞定无水印高清视频下载完整指南
  • 不会写代码也能做AI副业?揭秘ChatGPT+Notion+Canva组合拳,1人1天产出20条爆款内容
  • CAD智能翻译技术解析与工程实践
  • 2026 年青岛幼儿园软包,淘气堡防撞软包定制,本地加工商家实测分享 - LYL仔仔
  • Unity串口通信实战:工业数字孪生项目中的循环读写与协议解析