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

单例模式 懒汉式(静态内部类)

/*** 单例模式* 懒汉式 方式6 静态内部类* 优点:利用JVM类加载机制保证延迟加载和线程安全。*/
public class SingletonInnerClass {// 1、私有构造方法private SingletonInnerClass() {}private static class SingletonInnerClassHolder {// 2、声明对象private static final SingletonInnerClass INSTANCE = new SingletonInnerClass();}// 3、对外提供public方法获取唯一实例public static SingletonInnerClass getInstance() {return SingletonInnerClassHolder.INSTANCE;}}

这种写法巧妙地利用了 Java 语言的特性,把“多线程同步”和“内存可见性”等复杂问题,全部甩锅给了 JVM 处理。

1. 为什么它是“懒加载”的?(Lazy Loading)

根本原因:加载外部类,不会自动加载静态内部类。

  • 启动时: 当程序启动,或者用到 SingletonInnerClass 这个外部类时,JVM 加载了外部类。但此时,内部类 SingletonInnerClassHolder 并没有被加载
  • 运行时: 只有当第一次调用 getInstance() 方法时,代码里引用了 SingletonInnerClassHolder.INSTANCE
  • 触发点: 此时,JVM 才会去加载、连接、初始化这个内部类。
  • 结果: 这就实现了“不到万不得已(调用 getInstance),绝不创建对象”的懒加载效果。

2. 为什么它是“线程安全”的?

没有在代码里写任何 synchronized,那并发时怎么办?

根本原因:JVM 在加载类的时候,是自带“锁”的。

  • JVM 的承诺: 虚拟机会保证一个类的初始化(Initialization)过程在多线程环境中被正确地加锁、同步。
  • 过程还原:
  1. 线程 A 和线程 B 同时调用 getInstance()
  2. 它们同时试图访问 SingletonInnerClassHolder
  3. JVM 发现这个内部类还没加载,于是开始加载它。
  4. JVM 自动加锁: JVM 保证只有一个线程能执行这个类的初始化代码(即执行 static 块或初始化 static 变量)。
  5. 线程 A 抢到了初始化权,执行 new SingletonInnerClass()
  6. 线程 B 只能等待。
  7. 等 A 初始化完毕,锁释放。B 拿到的就是已经完全创建好的 INSTANCE

结论: 这里的线程安全不是靠你写的代码保证的,而是靠 JVM 底层的类加载锁 保证的。


3. 为什么不需要 volatile

在双重检查锁(DCL)中,我们需要 volatile 是为了防止指令重排序导致其他线程拿到“半成品”对象。

在这里不需要 volatile,是因为 Java 内存模型 (JMM) 对类的初始化阶段做了特殊的规定(Happens-Before 关系):

  • 类加载的屏障: 只有当一个类被完全初始化之后,它的静态变量才会被暴露给其他线程。
  • 原子性保证: static final ... INSTANCE = new ... 这行代码是在类加载阶段执行的。JVM 保证了在类加载完成之前,其他线程根本看不到 INSTANCE 这个变量。
  • 结果: 当其他线程能访问到 INSTANCE 时,它一定已经是一个初始化完成的完整对象了。不存在“先赋值引用、后初始化构造方法”的重排序并发风险。

http://www.jsqmd.com/news/314147/

相关文章:

  • Thinkphp和Laravel+vue服装定制晋祠宋明服饰文化体验平台_ye471 景区古典服装商城定制系统
  • 多线程锁基础
  • 9款AI写论文哪个好?实测后锁定宏智树AI:文献真实、数据可溯,毕业论文一键通关!官网www.hzsxueshu.com 微信公众号搜一搜宏智树AI
  • 5 款 AI 写论文哪个好?实测后发现,宏智树 AI 才是毕业论文兜底神器
  • 写论文软件哪个好?宏智树 AI 封神!从选题到答辩的全流程攻略
  • “AI+虚拟仿真”重塑环艺设计人才培养
  • 加油卡小程序核心玩法拆解与运营逻辑分析
  • 只有10%的人会相信网络广告
  • 基于python的档案宝微信小程序
  • Thinkphp和Laravel+vue图书在线销售商城的设计与实现echart 商家可视化 验证码
  • 推荐 Prompt 模板(大幅提升 JSON 质量)
  • 讲解唯品花消费购物额度如何取出来变现
  • 基于SpringBoot + Vue的医院预约挂号系统的设计与实现
  • 基于SpringBoot + Vue的在线采购系统
  • 基于SpringBoot + Vue的校园社团信息管理系统
  • 亲测好用!8款AI论文软件测评:本科生毕业论文必备
  • 基于SpringBoot + Vue的高校学生兼职服务平台的设计与实践
  • 【通信】基于Matlab模拟DVB-RCS信号传输,双用户时隙 + 载波调制解调
  • 从 YOLOv5n 到 OpenVINO INT8 ≤2MB一个课堂手机检测系统的工程化落地实践
  • 脑机接口数据处理连载(十二) 脑机接口数据标签设计与规范实战
  • 年底采购更省钱?用AI精准对接本地工厂,绕过中间商拿出厂价
  • 【Android 美颜相机】第二十一天:GPUImageChromaKeyBlendFilter (颜色加深混合滤镜)
  • 揭秘唯品会商城唯品花消费额度怎么使用以及提现流程
  • 目标检测算法应用工程师 面试高频题 + 标准答案
  • KB1240/KB1241对射光电的使用
  • 吐血推荐研究生必用TOP8 AI论文软件:开题报告文献综述全测评
  • Clawdbot集成数眼智能联网搜索API完整教程
  • 管家婆分销软件中如何进行现金流量分配
  • 基于javaweb技术与SSM框架的智慧商城平台的设计与实现(11819)
  • 基于SSM的“昭愿”甜品店销售管理系统(11820)