.NET之C#编程:懒汉模式的终结,单例模式的正确打开方式

概述

在C#编程世界中,单例模式是一种常见的设计模式,用于确保一个类只有一个实例,并提供一个全局访问点。然而,传统的懒汉模式实现方式在多线程环境下存在安全隐患。本文将深入探讨单例模式的正确实现姿势,带你走出懒汉模式的误区,掌握单例模式的高级玩法。

单例的正确打开方式

一、单例模式的基本概念单例模式确保一个类在任何情况下都只有一个实例,并且提供一个全局访问点。这在配置管理、连接池等场景中非常有用。

二、懒汉模式的陷阱懒汉模式在第一次调用GetInstance方法时才会创建实例,看起来简单,但在多线程环境下,可能会创建多个实例。

复制代码
cs 复制代码
public class LazySingleton
{
    private static LazySingleton instance;
    private LazySingleton() { }


    public static LazySingleton GetInstance()
    {
        if (instance == null)
        {
            instance = new LazySingleton();
        }
        return instance;
    }
}

使用场景:单例实例在多线程访问前不需要初始化。优点:延迟加载,节省资源。缺点:多线程环境下不安全。

三、线程安全的懒汉模式通过lock关键字确保线程安全,但这种方式存在性能瓶颈。

复制代码
cs 复制代码
private static readonly object lockObject = new object();
public static Singleton GetInstance()
{
    if (instance == null)
    {
        lock (lockObject)
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
        }
    }
    return instance;
}

使用场景:需要确保线程安全的单例。优点:线程安全。缺点:性能开销大。

四、静态初始化器的单例模式C#的静态初始化器是线程安全的,并且不需要使用lock,这是实现单例模式的一种简洁方式。

复制代码
cs 复制代码
public class StaticInitializerSingleton
{
    private static readonly StaticInitializerSingleton instance = new StaticInitializerSingleton();
    private StaticInitializerSingleton() { }


    public static StaticInitializerSingleton GetInstance()
    {
        return instance;
    }
}

使用场景:适用于大多数单例模式需求。优点:简洁,线程安全。缺点:实例在类加载时就创建,无法延迟加载。

五、使用Singleton属性通过一个静态只读属性来实现单例,这种方式同样利用了静态初始化的线程安全性。

复制代码
cs 复制代码
public class ReadOnlySingleton
{
    private static readonly ReadOnlySingleton instance = new ReadOnlySingleton();
    private ReadOnlySingleton() { }


    public static ReadOnlySingleton Instance { get { return instance; } }
}

使用场景:需要通过属性访问单例实例。优点:简洁,线程安全。缺点:同静态初始化器。

六、双重检查锁定模式双重检查锁定模式是懒汉模式的一个改进,它既保证了线程安全,又避免了不必要的锁。

复制代码
cs 复制代码
public class DoubleCheckedLockingSingleton
{
    private static readonly object lockObject = new object();
    private static DoubleCheckedLockingSingleton instance;


    public static DoubleCheckedLockingSingleton GetInstance()
    {
        if (instance == null)
        {
            lock (lockObject)
            {
                if (instance == null)
                {
                    instance = new DoubleCheckedLockingSingleton();
                }
            }
        }
        return instance;
    }
}

使用场景:需要延迟加载的单例,且要求线程安全。优点:线程安全,延迟加载。缺点:代码复杂。

七、使用静态构造函数静态构造函数在类首次加载时执行,可以用来初始化静态成员,但这种方式不支持延迟加载。

复制代码
cs 复制代码
public class StaticConstructorSingleton
{
    private static readonly StaticConstructorSingleton instance;


    static StaticConstructorSingleton()
    {
        instance = new StaticConstructorSingleton();
    }


    private StaticConstructorSingleton() { }


    public static StaticConstructorSingleton GetInstance()
    {
        return instance;
    }
}

使用场景:类加载时需要初始化的单例。优点:线程安全,无需手动同步。缺点:不支持延迟加载。

八、总结单例模式的实现方式多种多样,每种方式都有其适用场景和优缺点。在实际开发中,我们应该根据具体需求选择合适的实现方式。对于大多数情况,推荐使用静态初始化器的方式,因为它简洁且线程安全。如果需要延迟加载,可以考虑使用双重检查锁定模式。

结语:单例模式是C#编程中的经典模式,正确实现单例模式不仅可以保证程序的稳定性,还可以提高代码的可维护性。希望通过本文的探讨,能够帮助大家避免使用懒汉模式,掌握单例模式的正确实现方式,写出更加优雅、高效的代码。

往期精品推荐:

在国内默默无闻的.NET,在国外火的超乎想象?

C#的膨胀之路:创新还是灭亡

介绍.NET 6款好看的winform开源UI库

介绍一款最受欢迎的.NET 开源UI库

WPF第三方开源UI框架:打造独特体验的魔法师

WPF与Winform,你的选择是?

WinForm的前世今生

.NET成年了,然后呢?------编程界的逆袭传奇

相关推荐
你怎么知道我是队长5 小时前
C语言---头文件
c语言·开发语言
期待のcode5 小时前
Java虚拟机的运行模式
java·开发语言·jvm
我是唐青枫5 小时前
C#.NET ConcurrentDictionary<TKey, TValue> 深度解析:原理与实践
c#·.net
hqwest5 小时前
码上通QT实战25--报警页面01-报警布局设计
开发语言·qt·qwidget·ui设计·qt布局控件
a程序小傲5 小时前
京东Java面试被问:动态规划的状态压缩和优化技巧
java·开发语言·mysql·算法·adb·postgresql·深度优先
HellowAmy5 小时前
我的C++规范 - 玩一个小游戏
开发语言·c++·代码规范
徐先生 @_@|||6 小时前
Palantir Foundry 五层架构模型详解
开发语言·python·深度学习·算法·机器学习·架构
tang777897 小时前
爬虫如何绕过绕过“5秒盾”Cloudflare:从浏览器指纹模拟到Rust求解之不完全指南
开发语言·爬虫·rust·cloudflare
Yuer20257 小时前
什么是 Rust 语境下的“量化算子”——一个工程对象的最小定义
开发语言·后端·rust·edca os·可控ai
hqwest7 小时前
码上通QT实战26--系统设置01-系统设置布局
开发语言·qt·qss·qt基础控件·qt布局控件·qt表格控件