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

设计模式 - 单例模式 - Tips

为什么双重检查会带来空指针异常问题?

if (instance == null) {             synchronized (Singleton.class) {                                 if (instance == null) {                     instance = new Singleton();                 }             }         
}

instance = new Singleton();

上述加粗的代码并不是原子操作,包含三个步骤:

  1. 为 Singleton 分配内存地址

  2. 执行 Singleton() 构造方法,初始化成员变量等

  3. 将内存地址赋值给 instance 变量

假设线程 A 正在执行:

instance = new Singleton();   

由于指令重排序,线程 A 可能在构造函数执行之前,就已经将内存地址赋值给 instance,导致 instance 变为非 null。此时线程 B 会认为 instance 已经是合法对象,于是直接使用,结果可能:

  • 访问尚未初始化的字段

  • 抛出 NullPointerException

  • 出现逻辑错误或不可预知的行为

为什么可以通过静态内部类实现懒汉式单例模式

public class Singleton {     private Singleton() {}     private static class SingletonHolder {         private static final Singleton INSTANCE = new Singleton();     }        public static Singleton getInstance() {              return SingletonHolder.INSTANCE; }  
}

这依赖于 Java 类加载机制的特性:

  • JVM 在加载外部类的过程中不会加载静态内部类,只有内部类的属性 / 方法被调用时才会进行加载(懒汉式

  • JVM 在加载类的时候会自动保证线程安全,一个类在 JVM 中只会被加载一次

http://www.dtcms.com/a/196412.html

相关文章:

  • [ctfshow web入门] web77
  • OpenCV 特征检测全面解析与实战应用
  • AI知识梳理——RAG、Agent、ReAct、LangChain、LangGraph、MCP、Function Calling、JSON-RPC
  • 【滑动窗口】LeetCode 209题解 | 长度最小的子数组
  • 系统架构设计(七):数据流图
  • 使用Docker部署Nacos
  • 【C++详解】string各种接口如何使用保姆级攻略
  • 区块链可投会议CCF C--IPCCC 2025 截止6.7 附录用率
  • 共享内存【Linux操作系统】
  • 【爬虫】DrissionPage-6
  • JavaScript【6】事件
  • 进阶-数据结构部分:​​​​​​​2、常用排序算法
  • 动态规划(3)学习方法论:构建思维模型
  • MATLAB2025新功能
  • 2025/517学习
  • STM32 | FreeRTOS 消息队列
  • Flink 数据传输机制
  • 6.1.1图的基本概念
  • DeepSeek快速指南:提升效率,告别内耗
  • 深入理解 requestIdleCallback:浏览器空闲时段的性能优化利器
  • OpenCV级联分类器
  • webpack 学习
  • Git 项目切换到新的远程仓库地址
  • NVMe简介6之PCIe事务层
  • 框架之下再看HTTP请求对接后端method
  • PLC和变频器之间如何接线
  • Java 快速转 C# 教程
  • 科技晚报 AI 速递:今日科技热点一览 丨 2025 年 5 月 17 日
  • 网关GateWay——连接不同网络的关键设备
  • 【蓝桥杯省赛真题51】python石头运输 第十五届蓝桥杯青少组Python编程省赛真题解析