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

Java线程安全的单例模式如何实现 双重检查锁定原理

单例模式实现线程安全,双重检查锁定(Double-Checked Locking)它是一种常见而有效的写作方法。它不仅保证了性能,而且保证了多线程环境中唯一的例子。

单例模式的基本要求

单例模式的核心是:一个类别只允许创建一个例子,并提供一个全球访问点。在多线程场景中,必须防止多线程同时创建多个例子。

常见的实现方式包括:

  • 饿汉风格:类加载初始化,线程安全,但可能浪费资源
  • 懒汉风格:只有在第一次使用时才能创建,线程安全问题需要处理
  • 双重检查锁:延迟加载 + 高效的线程安全

实现代码的双重检查锁定

public class Singleton { // 使用 volatile 关键字确保多线程内存的可见性,并禁止指令重新排序 private static volatile Singleton instance; // 私有构造函数,防止外部实例化 private Singleton() {} // 获取实例的公共静态方法 public static Singleton getInstance() { if (instance == null) { // 第一次检查:避免不必要的同步 synchronized (Singleton.class) { // 加锁 if (instance == null) { // 第二次检查:确保只创建一次 instance = new Singleton(); // 创建实例 } } } return instance; } }

双检锁定原理分析

这种写作方法之所以有效,是因为它降低了同步成本。只有在实例没有创建时才会锁定。一旦创建完成,后续调用将直接返回引用,无需同步。

  • 第一次检查 instance == null:如果存在实例,直接返回,不进入同步块,提高性能
  • synchronized 确保只有一个线程能同时进入临界区
  • 第二次检查 instance == null:防止多个线程在第一次检查后进入同步块,导致重复创建
  • volatile 防止对象创建过程中的指令重新排序

new Singleton() 不是原子操作,大致分为三个步骤:

  1. 内存空间的分配
  2. 调用构造函数的初始对象
  3. 将 instance 指向内存地址

由于 JVM 对于处理器的优化,可能会对指令进行重新排序,如执行第一步和第三步,然后执行第二步。此时,如果此时正好读取另一个线程 instance,会发现它非 null,但对象还没有完全初始化,导致错误。

volatile 这种重排序可以被禁止,以确保对象在结构完成前不会被其他线程看到。

为什么不加 volatile 会有问题?

在没有 volatile 在修改过程中,线程A在创建对象时进行了重新排序,线程B可能会被“半初始化”对象引用,并且在调用其方法时会出现不可预测的行为。此外 volatile 后,JVM 将内存屏障插入其他线程,以确保正确的结构顺序 always 是完整构造后的例子。

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

相关文章:

  • 2026重庆口碑好的助听器厂家盘点,合规靠谱+服务优质,速看优选名单 - 深度智识库
  • 效果实测:IndexTTS2 V23版高采样率输出,人声更具“空气感”
  • 手把手做 200W LLC 电源:基于 LP9960 全流程设计避坑实战(原理图 + PCB+BOM)
  • 思源宋体TTF:企业级开源中文字体的价值与应用指南
  • [ 前端基础知识学习 ] Day 5
  • 2026年重庆新能源汽车公司推荐:重庆珂星汽车销售服务有限公司6-8方车/3.7-4.2米轻卡全系供应 - 品牌推荐官
  • 2026云南镀锌管厂家实用参考 适配大棚建筑桥梁工程 耐腐适配西南气候 - 深度智识库
  • 西门子S7 - 200 PLC与组态王构建旋转式滤水器控制系统
  • 终极指南:如何用MelonLoader打造你的Unity游戏模组世界 [特殊字符]
  • 20251918 2025-2026-2《网络攻防实践》第二周作业
  • 5大核心优势!Thermo:化工工程师的开源热力学计算引擎
  • Phi-3-mini-128k-instruct快速部署:使用Docker Compose一键启动
  • 【全栈实战】Spring AI + MCP:手把手教你实现“指数基金实时估值”与 AI 全链路观测系统
  • 小红书笔记采集总报错?别再用懒加载指令了,试试这个虚拟列表的破解方案
  • 解放游戏进度:Apollo Save Tool让PS4存档管理不再复杂
  • FUTURE POLICE实战:在线教育视频字幕自动对齐方案
  • 2026年国内最值得推荐的AI Agent(智能体)工具有哪些?深度解析企业级智能自动化选型指南
  • 3步揭秘存储设备真实容量:实战避坑指南
  • STM32 进阶封神之路(二十五):ESP8266 深度解析 —— 从 WiFi 通信原理到 AT 指令开发(底层逻辑 + 实战基础)
  • 20260319-编程踩坑总结
  • 跨平台实战:Windows/macOS同步部署OpenClaw与Qwen3.5-4B-Claude
  • Python百度搜索API:免费无限制的搜索引擎集成终极方案
  • 京东评论和评论数api接口
  • 4个步骤掌握PacketFence:构建企业级网络准入控制体系
  • 电源调试避坑实战:7个量产踩坑点+手把手教程,新手也能零失误
  • Python入门者的CasRel模型初体验:三行代码实现关系抽取
  • 3个技巧让智能提取字幕工具成为你的视频学习助手
  • Klipper 3D打印机固件故障诊断指南:从异常识别到根本解决
  • OpenClaw Skills管理实战:130+Agents环境下的技能共享与调用指南(建议收藏)
  • MedGemma 1.5应用指南:就医前如何用AI整理症状和问题