7.单例模式是否必须加锁

  1. 7.单例模式是否必须加锁
    1. 7.1 题目
    2. 7.2 深入解析
    3. 7.3 答题示例
    4. 7.4 关键词联想

7.单例模式是否必须加锁


7.1 题目

单例模式中为什么要加锁?是否是必须的?


7.2 深入解析

加锁的目的是为了解决线程安全问题,避免多个线程同时访问单例。
同时访问单例可能带来的问题:
1.导致多个实例的创建,违背了单例唯一性的设计原则
2.避免同时修改访问单例中成员
等等

加锁并不是必须的,如果你的项目中不存在多线程同时访问单例的情况,那么可以不用加锁


7.3 答题示例

给单例加锁主要是为了 保证线程安全,防止在多线程环境下出现多次实例化或并发修改实例状态的问题。

  1. 在双重检查锁(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;
        }
    }
    
  2. 如果应用场景 不涉及多线程 或者单例在启动时即初始化(静态构造函数),则可以省去锁机制:

    // 静态初始化,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

×

喜欢就点赞,疼爱就打赏