7.单例模式是否必须加锁
7.1 题目
单例模式中为什么要加锁?是否是必须的?
7.2 深入解析
加锁的目的是为了解决线程安全问题,避免多个线程同时访问单例。
同时访问单例可能带来的问题:
1.导致多个实例的创建,违背了单例唯一性的设计原则
2.避免同时修改访问单例中成员
等等
加锁并不是必须的,如果你的项目中不存在多线程同时访问单例的情况,那么可以不用加锁
7.3 答题示例
给单例加锁主要是为了 保证线程安全,防止在多线程环境下出现多次实例化或并发修改实例状态的问题。
在双重检查锁(Double-Check Locking)中,只有第一次实例化时才进锁,减少性能开销:
private static readonly object _lock = new object(); private static Singleton _instance; public static Singleton Instance { get { if (_instance == null) { lock (_lock) { if (_instance == null) _instance = new Singleton(); } } return _instance; } }如果应用场景 不涉及多线程 或者单例在启动时即初始化(静态构造函数),则可以省去锁机制:
// 静态初始化,CLR 保证线程安全 public class Singleton { public static readonly Singleton Instance = new Singleton(); private Singleton() {} }总结:加锁不是必须的,只在真正多线程竞争创建实例时才需要,否则静态构造或懒汉式单线程即可满足单例需求。
7.4 关键词联想
- 线程安全
- 双重检查锁定(Double‑Check Locking)
- 静态构造函数初始化
- 懒汉式 vs 饿汉式单例
- lock 关键字
- 内存屏障
- 并发与竞态条件
- CLR 静态初始化保证
- 性能开销 vs 安全性权衡
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com