.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成年了,然后呢?------编程界的逆袭传奇

相关推荐
TAN-90°-1 小时前
Java 5——final 抽象 接口
java·开发语言
Andy1 小时前
C++ 容器适配器_栈_队列_双端队列
开发语言·网络·c++
吴声子夜歌1 小时前
Java——显示锁
java·开发语言
思麟呀1 小时前
在C++基础上理解Csharp-2
开发语言·jvm·c++·c#
桀人1 小时前
类和对象——上篇
开发语言·c++
zzzsde1 小时前
【Linux】线程概念与控制(3):线程ID&&C++封装线程
linux·运维·服务器·开发语言·算法
消失的旧时光-19431 小时前
C 语言如何实现“面向对象”?—— 从 struct + 函数指针,到 Linux 内核设计思想
linux·c语言·开发语言
喵叔哟1 小时前
11.【.NET10 实战--孢子记账--产品智能化】--接入第三方平台
.net·openai
小短腿的代码世界1 小时前
Qt时间日期处理与QTimer高级应用:从毫秒级精度到跨平台定时器的完整架构解析
开发语言·qt·架构
TAN-90°-2 小时前
Java 6——成员变量初始值 object equals和== toString instanceof 参数传递问题
java·开发语言