单例模式的几种方法

mac2022-06-30  86

单例模式

1.不好的解法(只适用于单例模式)

把构造函数设为私有函数以禁止他人创建。定义一个静态实例,在需要的时候创建该实例。

1 public sealed class Singleton1 2 { 3 //私有方法创建Singleton1 4 private Singleton1(){ 5 } 6 7 private static Singleton1 instance = null; 8 public static Singleton1 Instance 9 { 10 get{ 11 if(instance == null) 12 instance = new Singleton1(); 13 14 return instance; 15 } 16 } 17 }

 

只适合单线程,如果多线程同时运行到判断语句,会创建多个实例。

2.不好的解法(适应多线程,低效率)

对第一种方法的改进,可以通过添加一个同步锁。

public sealed class Singleton2 { //私有方法创建Singleton2 private Singleton2(){ } private static readonly object syncObj = new object(); private static Singleton2 instance = null; public static Singleton2 Instance { get{ lock(syncObj){ if(instance == null) instance = new Singleton2(); } return instance; } } }

 

此时只有一个线程可以得到同步锁。其他的线程只能等待,等第一个线程执行完创建实例或得到实例后,其他线程再依次进行获得同步锁和判断。

3.可行解法 加锁前后两次判断实例

第二种方法在每次线程都会执行同步锁,而同步锁是一个效率很低费时间的操作,所以要避免加锁操作。我们在实例还没有创建前需要加锁,之后就不需要加锁操作了,进一步改进如下:

public sealed class Singleton3 { //私有方法创建Singleton3 private Singleton3(){ } private static readonly object syncObj = new object(); private static Singleton3 instance = null; public static Singleton3 Instance { get { if(instance == null) { lock(syncObj){ if(instance == null) instance = new Singleton3(); } return instance; } } } }

4.推荐解法 利用静态构造函数

在c#中,静态构造函数只会被调用一次。可以利用这一特性进行单例模式。

public sealed class Singleton4 { private Singleton4(){ } private static Singleton4 instance = new Singleton4(); public static Singleton4 Instance { get{ return instance; } } }

 

5. 按需创建实例

public sealed class Singleton5 { Singleton5(){ } public static Singleton5 Instance{ get{ return Nested.instance; } } class Nested { static Nested(){ } internal static readonly Singleton5 instance = new Singleton5(); } }

 

转载于:https://www.cnblogs.com/Mask-D/p/10446835.html

最新回复(0)