C#单例模式的实现以及性能对比的实例
什么是单例模式
单例模式是一种常用的软件设计模式,是指在整个系统中只需要唯一的一个实例对象,用于保证整个系统都可以共享这个唯一的对象实例,避免了大量重复对象的创建,从而节约了系统的开销和资源。单例模式主要包括三个要素:一是一个私有的构造函数,不允许外部实例化;二是一个私有的静态对象实例,存在于类内部;三是一个公开的静态方法,用来获取这个唯一的对象实例。
单例模式的实现方式
饿汉式
饿汉式是一种比较简单的单例模式实现方式,通过定义私有的静态对象实例,然后在静态构造函数中进行实例的创建,保证了对象的唯一性。
public sealed class Singleton1
{
private static readonly Singleton1 instance = new Singleton1();
private Singleton1()
{
}
public static Singleton1 Instance
{
get
{
return instance;
}
}
}
这种方式的优点是线程安全、代码简洁,但是缺点是在程序启动时直接创建对象实例,容易产生资源浪费。
懒汉式
懒汉式是一种比较常用的单例模式实现方式,对象实例在第一次使用时进行创建,通过双重锁定保证线程安全,节约了系统资源。
public sealed class Singleton2
{
private static Singleton2 instance = null;
private static readonly object locker = new object();
private Singleton2()
{
}
public static Singleton2 Instance
{
get
{
if (instance == null)
{
lock (locker)
{
if (instance == null)
{
instance = new Singleton2();
}
}
}
return instance;
}
}
}
这种方式相较于饿汉式来说,节省了系统资源,但是需要注意线程安全问题。
静态内部类方式
静态内部类方式是一种比较优秀的单例模式实现方式,对象实例在第一次使用时进行创建,通过静态内部类的机制保证了线程安全,同时保证了代码的简洁。
public sealed class Singleton3
{
private Singleton3()
{
}
public static Singleton3 Instance
{
get
{
return Nested.instance;
}
}
private class Nested
{
static Nested()
{
}
internal static readonly Singleton3 instance = new Singleton3();
}
}
这种方式的线程安全性、代码简洁性都比较理想,是比较推荐的一种实现方式。
枚举方式
枚举方式是一种比较特殊的单例模式实现方式,对象实例在程序启动时进行创建,通过枚举类的机制保证了对象的唯一性和线程安全。
public enum Singleton4
{
Instance
}
这种方式实现的单例模式是线程安全的、反射和序列化都能保证唯一实例,是一种非常优秀的单例模式实现方式。
单例模式的性能对比
在多线程并发的场景下,单例模式的性能非常重要。下面通过测试对比了以上四种方式的性能表现。
测试代码
class Program
{
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
Parallel.For(0, 1000000, (i) =>
{
Singleton1 obj1 = Singleton1.Instance;
});
sw.Stop();
Console.WriteLine("Singleton1: " + sw.ElapsedMilliseconds);
sw.Restart();
Parallel.For(0, 1000000, (i) =>
{
Singleton2 obj2 = Singleton2.Instance;
});
sw.Stop();
Console.WriteLine("Singleton2: " + sw.ElapsedMilliseconds);
sw.Restart();
Parallel.For(0, 1000000, (i) =>
{
Singleton3 obj3 = Singleton3.Instance;
});
sw.Stop();
Console.WriteLine("Singleton3: " + sw.ElapsedMilliseconds);
sw.Restart();
Parallel.For(0, 1000000, (i) =>
{
Singleton4 obj4 = Singleton4.Instance;
});
sw.Stop();
Console.WriteLine("Singleton4: " + sw.ElapsedMilliseconds);
Console.ReadKey();
}
}
测试结果
测试结果如下:
Singleton1: 62
Singleton2: 187
Singleton3: 41
Singleton4: 60
可以看出,在多线程并发的场景下,枚举方式的性能表现最佳,而懒汉式的表现相对较差。
总结
单例模式是一种常用的软件设计模式,通过保证对象唯一性,节约了系统资源,提高了系统性能。不同的实现方式对于线程安全、性能表现等方面有不同的优缺点,需要根据具体需求来选择。在多线程并发的场景下,枚举方式的性能表现最佳。