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

设计模式:单例模式

一、单例模式介绍

1、定义

单例模式是Java中最简单的设计模式之一,此模式保证 某个类在运行期间,只有一个实例对外提供服务,而这个类被称为单例类

2、使用单例模式要做的两件事

  • 保证一个类只有一个实例
  • 为该实例提供一个全局访问点

二、饿汉式

1、特点

        在类加载期间初始化私有的静态实例,保证instance实例创建过程式线程安全的。

// 饿汉式
public class Singleton01 {// 私有化构造方法:禁止外部通过new的方式创建对象private Singleton01(){}// 通过static 在类加载期间创建私有化静态实例// 静态实例属于类,在类加载时会创建出来,并且只创建一次。这样可以保证线程安全,因为拿到的始终时同一个对象private static Singleton01 instance = new Singleton01();// 提供全局访问点public static Singleton01 getInstance(){return instance;}
}

二、懒汉式(线程不安全)

1、特点

        支持懒加载(延迟加载),只有调用getInstance方法时,才会创建对象

2、问题 

在多线程下,会有线程安全问题。

        线程A 进入if判断后,还没new操作。线程B也通过if判断了。这样线程A、B 都会进行new操作。获取到两个不同的对象

// 懒汉式
public class Singleton02 {// 私有化构造方法:防止外部通过new的方式创建对象private Singleton02(){}// 不再这里创建对象了,调用getInstance方法时才创建private static Singleton02 instance;// 在调用getInstance方法中,判断没创建对象就新new一个对象返回public static Singleton02 getInstance(){if (instance == null){return new Singleton02();}return instance;}
}

      

三、懒汉式(线程安全)

1、特点

通过使用synchronized 锁,锁住单例模式对象的方法,防止多个线程同时调用问题。

2、缺点

对方法加了synchronized锁,并发就很低。

class Singleton03{private Singleton03(){}private static Singleton03 instance;//通过添加 synchronized 保证多线程模式下,单例模式对象的唯一性。public static synchronized Singleton03 getInstance(){if (instance == null){return new Singleton03();}return instance;}
}

四、懒汉式-双重校验

// 懒汉式 双重校验
public class Singleton04{private Singleton04(){}// 加volatile保证变量的可见性、屏蔽指令重排序private volatile static Singleton04 instance;// 通过添加 synchronized 保证多线程模式下,单例模式对象的唯一性。public static Singleton04 getInstance(){// 第一次判断,如果instance不为null,不进入抢锁阶段,直接返回实例if (instance == null){// 第二次判断要等到抢到锁之后。synchronized (Singleton04.class) {if (instance == null) {instance =  new Singleton04();/*** 上面的创建对象的代码,在JVM 中被分为三步:*    1、分配内存空间*    2、初始化对象*    3、将instance指向分配好的内存空间*/}}}return instance;}
}

五、静态内部类(懒加载)

静态内部类的特性:在静态内部类中创建单例,在转载内部类的时候,才会创建单例对象。

就是只有在调用Singleton4Static 的时候才会去new 对象。

/*** 单例模式- 静态内部类 (懒加载)*  根据静态内部类的特性,同时解决了 延时加载 程序安全的问题,并且代码更加简洁*/
class Singleton05{private Singleton05(){}// 创建静态内部类private static class Singleton4Static{private static Singleton05 instance = new Singleton05();}public static Singleton05 getInstance(){return Singleton4Static.instance;}
}

六、反射对单例对象的破坏

反射破坏的原理

  1. 突破封装setAccessible(true) 覆盖了Java的访问控制检查

  2. 绕过初始化逻辑:直接调用构造方法,跳过了静态内部类的初始化控制

  3. 类加载机制失效:静态内部类方案依赖类加载保证单例,但反射在运行时创建新实例

class Reflect{public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {Class<Singleton05> clazz = Singleton05.class;Constructor<Singleton05> constructor = clazz.getDeclaredConstructor();// 设置为true后就可以对 类中的私有成员进行操作了。constructor.setAccessible(true);Singleton05 instance01 = constructor.newInstance();Singleton05 instance02 = constructor.newInstance();System.out.println(instance01 == instance02);}
}

七、防止反射破坏(以Singleton05代码举例)

在私有无参构造方法中加一个判断。

class Singleton05{private Singleton05(){if (Singleton4Static.instance != null){throw new RuntimeException("不允许非法访问");}}// 创建静态内部类private static class Singleton4Static{private static Singleton05 instance = new Singleton05();}public static Singleton05 getInstance(){return Singleton4Static.instance;}
}

http://www.xdnf.cn/news/1219159.html

相关文章:

  • RabbitMQ 消费者确认 (Ack/Nack) (With Spring Boot)
  • 10. NAT,代理服务,内网穿透
  • DoRA详解:从LoRA到权重分解的进化
  • coze 开源版 coze-studio 配置域名 处理上传问题 教程
  • JAVA后端开发:使用 MapStruct 实现 Java 对象映射
  • uni-app用css编写族谱树家谱树
  • USRP捕获手机/路由器数据传输信号波形(下)
  • Java试题-选择题(2)
  • Python爬虫07_Requests爬取图片
  • 如何将照片从 realme 手机传输到电脑?
  • 设计模式之代理模式
  • 网关 + MDC 过滤器方案,5分钟集成 日志 traceid
  • React中的this绑定
  • node.js之Koa框架
  • Linux Flathub软件管理方法 使用指南
  • [12月考试] E
  • 进程控制:从创建到终结的完整指南
  • 【Django】-1- 开发项目搭建
  • MongoDB系列教程-第四章:MongoDB Compass可视化和管理MongoDB数据库
  • 抓大鹅小游戏微信抖音流量主小程序开源
  • HUD抬头显示器-杂散光测试设备 太阳光模拟器
  • AI学习笔记三十三:基于Opencv的单目标跟踪
  • 对git 熟悉时,常用操作
  • day36 力扣1049.最后一块石头的重量II 力扣494.目标和 力扣474.一和零
  • 【LeetCode 热题 100】4. 寻找两个正序数组的中位数——(解法一)线性扫描
  • [论文阅读] 人工智能 + 软件工程 | KnowledgeMind:基于MCTS的微服务故障定位新方案——告别LLM幻觉,提升根因分析准确率
  • SFT最佳实践教程 —— 基于方舟直接进行模型精调
  • 构型空间(Configuration Space,简称C-space)
  • 全基因组关联分析(GWAS)中模型参数选择:MLM、GLM与FarmCPU的深度解析
  • 数据库中使用SQL作分组处理01(简单分组)