C#实现单例模式的多种方式
单例模式是设计模式中的一种,指的是创建一个类的实例后,该类只允许创建一个实例,并且提供一个访问该实例的全局访问点。在很多场景下,单例模式被广泛使用,比如线程池、缓存、配置文件等等。
在C#中实现单例模式的方式比较多,下面就介绍一些常见的实现方式,分别是:懒汉式、饿汉式、静态构造器、枚举实现、双重锁定以及 .NET 4.0+ 中新增的 Lazy
1. 懒汉式
懒汉式是指在调用获取实例的方法时才实例化对象,即只有当需要使用实例时才会去创建,因此称之为“懒汉式”。
这种方式比较简单,代码如下:
public sealed class Singleton
{
private static Singleton instance = null;
private Singleton() { }
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
在上面的代码中,我们在访问 Instance
属性时,会先检查 instance
是否为 null
,如果是,则创建一个新的 Singleton
实例,否则直接返回单例对象。
需要注意的是,这种方式并不是线程安全的,会存在多线程同时调用 Instance
属性时会创建多个实例的问题。
2. 饿汉式
相比懒汉式,饿汉式是指在程序启动时就创建好单例对象,因此称之为“饿汉式”。
这种方式比较简单,代码如下:
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton() { }
public static Singleton Instance
{
get
{
return instance;
}
}
}
在上面的代码中,instance
被声明为 readonly
,确保在多线程访问时不会被修改,因此是线程安全的。
3. 静态构造器
静态构造器是指在第一次使用类之前,.NET框架会自动调用静态构造函数来执行一些初始化操作,因此我们可以在静态构造函数中创建单例对象,示例代码如下:
public sealed class Singleton
{
private static readonly Singleton instance = null;
static Singleton()
{
instance = new Singleton();
}
private Singleton() { }
public static Singleton Instance
{
get
{
return instance;
}
}
}
如上代码,静态构造器会在第一次访问 Singleton
类之前被执行,因此可以在其中执行一些初始化操作,比如创建单例对象。
需要注意的是,如果单例类的静态构造函数中抛出了异常,那么 instance
将不会被赋值,因此使用时需要特别小心。
4. 枚举实现
在 .NET 2.0 之后,C#对枚举类型进行了扩展,可以将枚举类型看做是一种特殊的单例模式实现方式。
示例代码如下:
public enum Singleton
{
Instance
}
在上面的代码中,我们把 Singleton
定义为一个枚举类型,其只有一个成员 Instance
。当我们需要访问单例对象时,只需要使用 Singleton.Instance
即可获得。
需要注意的是,枚举类型的实现方式比较巧妙,但是其存在一些限制,比如无法继承和延迟初始化等。
5. 双重锁定
双重锁定是指在判断实例是否为 null
时,使用了两个锁来确保线程安全,因此称之为“双重锁定”。
示例代码如下:
public sealed class Singleton
{
private static readonly object syncObj = new object();
private static Singleton instance = null;
private Singleton() { }
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncObj)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
}
在上面的代码中,我们使用了两个锁 syncObj
和 instance
,并使用了两次 if
语句进行判断。
需要注意的是,双重锁定的实现方式比较复杂,而且可能存在一些细微的问题,比如CPU指令重排等问题。
6. Lazy实现
在 .NET 4.0 以及更高版本中,C#新增了一个 Lazy<T>
类型,可以方便地实现延迟初始化及线程安全,示例代码如下:
public sealed class Singleton
{
private static readonly Lazy<Singleton> lazyInstance = new Lazy<Singleton>(() => new Singleton());
private Singleton() { }
public static Singleton Instance
{
get
{
return lazyInstance.Value;
}
}
}
在上面的代码中,我们通过 Lazy<Singleton>
类型实现了单例对象的延迟初始化和线程安全,在调用 Instance
属性时才实例化对象,并且能够确保在多线程访问时只会创建一个实例。
需要注意的是,Lazy<T>
是一种非常优秀的实现方式,不仅易于使用,而且性能也比较高,需要尽量推荐使用。
总结
本文介绍了 C# 实现单例模式的多种方式,分别是懒汉式、饿汉式、静态构造器、枚举实现、双重锁定以及 .NET 4.0+ 中新增的 Lazy
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#实现单例模式的多种方式 - Python技术站