C# 单例模式实现方法 C#如何实现线程安全的单例模式

技术百科 畫卷琴夢 发布时间:2026-01-26 浏览:
直接 new Singleton() 不行,因静态字段初始化在多线程下不保证原子性,且无法延迟加载或控制时机;推荐用 Lazy 实现线程安全单例。

为什么直接 new Singleton() 不行

单例的核心是“全局唯一实例”,但裸写 private static Singleton instance = new Singleton(); 会触发类静态字段初始化,而 C# 的静态构造函数和字段初始化顺序在多线程下不保证原子性——尤其在 .NET Framework 早期版本中,可能创建多个实例。更关键的是,它无法控制初始化时机(比如依赖配置加载后才该创建),也不支持延迟加载。

推荐用 Lazy 实现线程安全单例

Lazy 是 .NET 4.0+ 内置的线程安全延迟初始化类型,默认使用 LazyThreadSafetyMode.ExecutionAndPublication,能确保只执行一次工厂逻辑、且所有线程看到的都是同一个实例。

  • 无需手动加锁,无死锁风险
  • 初始化失败会缓存异常,后续调用直接抛出,行为可预测
  • 支持传入自定义工厂函数,便于注入依赖或做条件判断
public sealed class Singleton
{
    private static readonly Lazy _instance = new Lazy(() => new Singleton());
public static Singleton Instance => _instance.Value;

private Singleton() { } // 私有构造,防止外部 new

}

双重检查锁定(DCL)还能用吗

能用,但必须严格满足三个条件:字段用 volatile、两次判空、锁内再次判空。稍有遗漏就会在 x86/x64 指令重排下失效,导致部分线程拿到未完全构造的对象(表现为字段为默认值或 NullReferenceException)。

  • volatile 防止编译器/CPU 重排构造函数指令
  • 第一次判空避免无谓加锁;第二次判空防止多个线程同时通过第一层检查后重复初始化
  • .NET Core 2.1+ 对 volatile 语义更严格,但 DCL 仍比 Lazy 多出几条 IL 指令和锁开销
public sealed class Singleton
{
    private static volatile Singleton _instance;
    private static readonly object _lock = new object();
public static Singleton Instance
{
    get
    {
        if (_instance == null)
        {
            lock (_lock)
            {
                if (_instance == null)
                    _instance = new Singleton();
            }
        }
        return _instance;
    }
}

private Singleton() { }

}

静态构造函数方式的隐含限制

写成 static Singleton() { _instance = new Singleton(); } 看似简洁,但它会在**首次访问任意静态成员或创建实例时触发**,时机不可控;而且一旦抛出异常,该类型将永久不可用(TypeInitializationException),连 Instance 属性都无法再访问。

  • 无法捕获初始化异常并降级处理
  • 不支持参数化构造(比如读取 appsettings.json 后再创建)
  • 在 ASP.NET Core 中,若单例依赖 IConfiguration,静态构造函数根本拿不到服务提供者

真正需要“绝对首次访问即创建”的场景极少,多数时候反而要避开它。


# 的是  # 都是  # 会在  # 加载  # 多个  # 首次  # app  # js  # json  # 对象  # c#  # 构造函数  # .net  # 为什么  # 线程  # Static  # 死锁  # private  # volatile  # 多线程  # 抛出  # 加锁  # 延迟加载 


相关栏目: <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 AI推广<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 SEO优化<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 技术百科<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 谷歌推广<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 百度推广<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 网络营销<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 案例网站<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 精选文章<?muma echo $count; ?>

相关推荐

在线咨询

点击这里给我发消息QQ客服

在线咨询

免费通话

24h咨询:4006964355


如您有问题,可以咨询我们的24H咨询电话!

免费通话

微信扫一扫

微信联系
返回顶部