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

设计模式之单例模式

目录

  • 一、简介
  • 二、单例模式实现方式
    • 1、饿汉式单例(推荐)
      • 饿汉式-方式1(**静态变量方式**)
      • 饿汉式-方式2(静态代码块方式)
    • 2、懒汉式单例
      • 懒汉式-方法1(线程不安全)
      • 懒汉式-方法2(线程安全)
      • 懒汉式-方法3(双重锁结构)
  • 三、单例破坏的方式
    • 1、反射攻击
    • 2、序列化攻击
    • 3、克隆攻击
    • 4、防御方式

一、简介

单例模式是oop(面向对象编程)语言的一种概念,顾名思义,就是一个类只能有一个实例对象。

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

二、单例模式实现方式

单例设计模式分类两种:
饿汉式:类加载就会导致该单实例对象被创建。
懒汉式:类加载不会导致该单实例对象被创建,而是首次使用该对象时才会创建。

1、饿汉式单例(推荐)

饿汉式-方式1(静态变量方式

这种方法通过将对象的实例设置为静态的方式,保证了该对象的实例,永远只有一份,且该对象的创建在类加载的时候就会立即创建在jvm内存中的方法区,在程序运行期间永久存在,所以当我们的对象太大的时候就会造成一种资源的浪费。(会产生大量类加载之后但是没有使用)

/** * 饿汉式 * 静态变量创建类的对象 */publicclassSingleton{//私有构造方法privateSingleton(){}//在成员位置创建该类的对象privatestaticSingletoninstance=newSingleton();//对外提供静态方法获取该对象publicstaticSingletongetInstance(){returninstance;}}

通过static关键字,在类加载时创建对象。

优化实现:

上述传统方式中,由于类加载时就实例化对象,因此当我们调用这个类的其它静态方法时,也会触发类加载,从而实例化单例独享,会导致空间的暂时浪费。

由于静态内部类中的对象不会默认加载,直到调用了获取该内部类属性的方法。因此可用静态内部类封装静态实例变量。

饿汉式-方式2(静态代码块方式)

对象的创建是在静态代码块中,也是对着类的加载而创建。所以和饿汉式的方式1基本上一样。

/** * 饿汉式-方法2 * 在静态代码块中创建该类对象 */publicclassSingleton{//私有构造方法privateSingleton(){}//在成员位置创建该类的对象privatestaticSingletoninstance;static{instance=newSingleton();}//对外提供静态方法获取该对象publicstaticSingletongetInstance(){returninstance;}}
classSingleton{// 私有构造函数privateSingleton(){}// 静态内部类privatestaticclassSingletonHolder{privatestaticSingletoninstance=newSingleton();}publicstaticSingletongetInstance(){returnSingletonHolder.instance;}}

2、懒汉式单例

懒汉式-方法1(线程不安全)

/** * 懒汉式 * 线程不安全 */publicclassSingleton{//私有构造方法privateSingleton(){}//在成员位置创建该类的对象privatestaticSingletoninstance;//对外提供静态方法获取该对象publicstaticSingletongetInstance(){if(instance==null){instance=newSingleton();}returninstance;}}

懒汉式-方法2(线程安全)

由于可能有多个线程同时要使用对象,因此需要考虑线程安全问题,防止并发访问时生成多个实例。

通常需要加锁来解决并发冲突,是用时间换空间的方案。

/** * 懒汉式 * 线程安全 */publicclassSingleton{//私有构造方法privateSingleton(){}//在成员位置创建该类的对象privatestaticSingletoninstance;//对外提供静态方法获取该对象,并且加锁publicstaticsynchronizedSingletongetInstance(){if(instance==null){instance=newSingleton();}returninstance;}}

懒汉式-方法3(双重锁结构)

双重检查锁模式是一种非常好的单例实现模式,解决了单例、性能、线程安全问题,但是呢,JVM在实例化对象的时候会进行优化和指令重排序操作,在多线程的情况下,就可能会出现空指针问题

对于上述对象的创建主要分为三个部分:

  • 分配对象的内存空间。
  • 初始化对象。
  • 设置instance指针指向对象所在的内存空间。

为了提高性能在JVM在实例化对象的时候会进行优化和指令重排序操作,也就是说有可能将我们上述的第七行和第九行代码进行顺序的交换。

/** * 双重检查方式 */publicclassSingleton{//私有构造方法privateSingleton(){}//使用volatile修饰,禁止重排序privatestaticvolatileSingletoninstance;//对外提供静态方法获取该对象publicstaticSingletongetInstance(){//第一次判断,如果instance不为null,不进入抢锁阶段,直接返回实际if(instance==null){synchronized(Singleton.class){//抢到锁之后再次判断是否为空if(instance==null){instance=newSingleton();}}}returninstance;}}

三、单例破坏的方式

1、反射攻击

publicclassSingleton{privatestaticfinalSingletonINSTANCE=newSingleton();privateSingleton(){// 私有构造}publicstaticSingletongetInstance(){returnINSTANCE;}}// 反射攻击代码:publicclassReflectionAttack{publicstaticvoidmain(String[]args)throwsException{Singletoninstance1=Singleton.getInstance();// 使用反射创建第二个实例Constructor<Singleton>constructor=Singleton.class.getDeclaredConstructor();constructor.setAccessible(true);// 突破私有访问限制Singletoninstance2=constructor.newInstance();System.out.println(instance1==instance2);// false!破坏了单例System.out.println("instance1: "+instance1);System.out.println("instance2: "+instance2);}}

通过类信息进行反射创建。

2、序列化攻击

importjava.io.*;publicclassSingletonimplementsSerializable{privatestaticfinalSingletonINSTANCE=newSingleton();privateSingleton(){}publicstaticSingletongetInstance(){returnINSTANCE;}}// 序列化攻击:publicclassSerializationAttack{publicstaticvoidmain(String[]args)throwsException{Singletoninstance1=Singleton.getInstance();// 序列化ByteArrayOutputStreambaos=newByteArrayOutputStream();ObjectOutputStreamoos=newObjectOutputStream(baos);oos.writeObject(instance1);// 反序列化(会创建新实例!)ByteArrayInputStreambais=newByteArrayInputStream(baos.toByteArray());ObjectInputStreamois=newObjectInputStream(bais);Singletoninstance2=(Singleton)ois.readObject();System.out.println(instance1==instance2);// false!}}

3、克隆攻击

publicclassCloneableSingletonimplementsCloneable{privatestaticfinalCloneableSingletonINSTANCE=newCloneableSingleton();privateCloneableSingleton(){}publicstaticCloneableSingletongetInstance(){returnINSTANCE;}@OverrideprotectedObjectclone()throwsCloneNotSupportedException{returnsuper.clone();// 默认实现会创建新实例}}// 攻击:CloneableSingletoninstance1=CloneableSingleton.getInstance();CloneableSingletoninstance2=(CloneableSingleton)instance1.clone();System.out.println(instance1==instance2);// false!

4、防御方式

// 方法1:使用统一的类加载器(应用类加载器)// 方法2:在getInstance()中检查类加载器publicclassClassLoaderSafeSingleton{privatestaticfinalClassLoaderSafeSingletonINSTANCE=newClassLoaderSafeSingleton();privateClassLoaderSafeSingleton(){// 检查类加载器ClassLoadercl=this.getClass().getClassLoader();if(cl!=ClassLoader.getSystemClassLoader()){thrownewRuntimeException("只能由系统类加载器加载");}}publicstaticClassLoaderSafeSingletongetInstance(){returnINSTANCE;}}
http://www.jsqmd.com/news/267805/

相关文章:

  • 麦橘超然可不可以换模型?扩展性分析
  • 米诺地尔哪个牌子好?权威评测结果出炉:蔓迪两剂型凭何包揽前二 - 博客万
  • 2026最新电商写字楼租赁推荐!广州优质商务办公空间权威榜单发布,产业聚合与专业服务双优助力企业高效发展 - 品牌推荐2026
  • OpenCV文档扫描仪部署教程:5分钟实现智能扫描
  • 九款高效智能摘要与润色工具的性能评测及用户体验对比
  • 2026年GEO公司招商加盟推荐:招商生态横向对比评测,解决线索低质与转化缓慢痛点 - 十大品牌推荐
  • Qwen2.5多语言支持:英文输出质量与调优实战
  • 金山平台绘就全球发展蓝图 - 博客万
  • 2026国内最新螺丝加工厂家最新top5排行榜发布!广东等地优质组合螺丝/端子螺丝/螺丝定制/螺丝加工公司及供应商综合实力盘点,品质与效率双优助力精密制造. - 品牌推荐2026
  • VHDL在FPGA逻辑设计中的应用:完整指南
  • 成都硕士留学机构口碑排名出炉,学员满意度高受认可 - 留学机构评审官
  • 2026 出海美国用工无忧:Safeguard Global 名义雇主服务优势盘点 - 品牌2025
  • 福州地区硕士留学中介top10,申请成功率高,值得信赖的选择 - 留学机构评审官
  • 白山市靖宇抚松长白英语雅思培训辅导机构推荐,2026权威出国雅思课程中心学校口碑排行榜 - 苏木2025
  • 合肥研究生留学中介top10盘点,资质正规机构选择指南 - 留学机构评审官
  • 2026南京A-Level培训机构推荐:优质教学机构盘点 - 品牌排行榜
  • beyond compare 4破解方法
  • 松原市宁江长岭乾安前郭尔罗斯扶余英语雅思培训辅导机构推荐,2026权威出国雅思课程中心学校口碑排行榜 - 苏木2025
  • 安装OpenCode后,无法使用。解决方案
  • 从单设备到全场景:用 Flutter + OpenHarmony 构建“超级应用”的完整架构指南 - 教程
  • 分期乐盒马鲜生套装新春回收年味更浓的方法 - 畅回收小程序
  • 差分隐私多元中位数的理论与应用
  • 2026年AI优化推荐:基于多行业实战评价,针对流量分散与转化痛点指南 - 十大品牌推荐
  • Java基础-核心知识点:方法参数传递机制 (值传递 vs. 引用传递)
  • 亲测好用!专科生毕业论文AI论文写作软件TOP9
  • AI漫剧干货:导演实战词库,几十个运镜指令详解与组合心法
  • 2026 广州出国英语雅思封闭式培训班课程口碑排名:权威测评 TOP5,高性价比提分推荐 - 老周说教育
  • 2026年AI优化推荐:基于工业与零售双场景评价,直击转化率低与效率低下痛点 - 十大品牌推荐
  • 为什么双十一零点你抢不到票?
  • 【收藏必备】ReAct范式详解:从入门到实践,让大模型拥有推理与行动能力