双重检查锁实现线程安全单例
时间:2026-02-13 08:21:38 332浏览 收藏
怎么入门文章编程?需要学习哪些知识点?这是新手们刚接触编程时常见的问题;下面golang学习网就来给大家整理分享一些知识点,希望能够给初学者一些帮助。本篇文章就来介绍《线程安全单例实现:双重检查锁详解》,涉及到,有需要的可以收藏一下
双重检查锁实现单例需用volatile修饰实例,防止指令重排序导致线程看到未初始化对象;标准写法含两次null检查与synchronized块;推荐静态内部类或枚举替代。

用双重检查锁(Double-Checked Locking)实现线程安全的单例,核心是减少同步开销,同时保证实例只被创建一次且可见性正确。关键在于 volatile 修饰实例变量,防止指令重排序导致其他线程看到未初始化完成的对象。
为什么需要 volatile
在没有 volatile 时,JVM 可能将单例对象的构造过程(分配内存 → 初始化 → 赋值给静态引用)重排序为:分配内存 → 赋值给静态引用 → 初始化。此时另一个线程可能读到非 null 的引用,但对象尚未初始化完毕,造成空指针或异常状态。
加上 volatile 后,禁止了该重排序,并确保后续读操作能看到初始化后的全部字段值(happens-before 语义)。
标准双重检查锁写法(Java)
以下是推荐的实现方式:
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) { // 第一次检查(无锁)
synchronized (Singleton.class) {
if (instance == null) { // 第二次检查(加锁后)
instance = new Singleton(); // volatile 保证原子性和可见性
}
}
}
return instance;
}
}
注意点:
- 构造函数必须私有,防止外部 new 实例
- instance 必须用 volatile 修饰,不可省略
- 两个 if (instance == null) 缺一不可:外层避免不必要的同步,内层防止重复创建
- synchronized 锁的是类对象(Singleton.class),确保全局唯一锁
其他安全且更简洁的替代方案
双重检查锁虽经典,但易出错。以下方式更推荐:
- 静态内部类(推荐):利用类加载机制保证线程安全与懒加载,无同步开销
- 枚举单例:天然线程安全、防反射/反序列化攻击,但不支持延迟加载
- 使用 Holder 模式(即静态内部类):代码简洁,JVM 保证仅在首次调用 getInstance 时才加载内部类并初始化实例
常见误区提醒
以下写法是错误或不安全的:
- 去掉 volatile —— 可能导致部分线程看到半初始化对象
- 把 synchronized 加在整个方法上(synchronized static getInstance)—— 效率低,每次调用都阻塞
- 用普通成员变量代替 static + volatile —— 不满足单例要求
- 在 getInstance 中直接 new 并赋值,无任何检查 —— 完全非线程安全
双重检查锁不是最简单的方式,但理解它有助于掌握并发编程中的可见性、有序性与同步粒度问题。实际项目中,优先考虑静态内部类或枚举方式。
本篇关于《双重检查锁实现线程安全单例》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于文章的相关知识,请关注golang学习网公众号!
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
415 收藏
-
151 收藏
-
189 收藏
-
350 收藏
-
155 收藏
-
432 收藏
-
165 收藏
-
340 收藏
-
342 收藏
-
346 收藏
-
336 收藏
-
452 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习