1 using System; 2 using System.Collections.Generic; 3
4 namespace ConsoleApp1 5 { 6 class Singleton 7 { 8 private static Singleton _singleton = null; 9 private static object singleton_Lock = new object(); //对象锁
10
11 /// <summary>
12 /// 标准的单例模式 13 /// </summary>
14 /// <returns></returns>
15 public static Singleton CreateInstance() 16 { 17 if (_singleton == null)//保证对象初始化之后的所有线程,不需要等待锁
18 { 19 lock (singleton_Lock)//保证只有一个线程进去判断
20 { 21 if (_singleton == null)//保证对象为空才创建
22 { 23 _singleton = new Singleton(); 24 } 25 } 26 } 27 return _singleton; 28 } 29 }//Class_end 30 }
第一种单例的写法,是用两个if加一个Lock来优化在多线程情况下调用单例的耗时,而下面是第二种写法(下图),效果一样,但更加简单
1 using System; 2 using System.Collections.Generic; 3
4 namespace ConsoleApp1 5 { 6 class Singleton 7 { 8 private static Singleton _Singleton = null; 9
10 /// <summary>
11 /// 静态构造函数:由CLR保证,在第一次调用之前调用,只调用一次 12 /// </summary>
13 static Singleton() 14 { 15 _Singleton = new Singleton(); 16 } 17
18 public static Singleton CreateInstance() 19 { 20 return _Singleton; 21 } 22 }//Class_end
23 }
第三种单例的写法更简单,直接在声明静态变量的时候创建实例化类
1 using System; 2 using System.Collections.Generic; 3
4 namespace ConsoleApp1 5 { 6 class Singleton 7 { 8 //静态变量会在类型第一次使用的时候初始化,而且只初始化一次
9 private static Singleton _singleton = new Singleton(); 10 public static Singleton CreateInstance() 11 { 12 return _singleton; 13 } 14 }//class_end
15 }
这三种单例的写法,其实效果都一样,只是后面两种是由系统CLR帮我们调用创建实例类。
单例的优点是:保证整个进程中该对象只被实例化一次,减少性能消耗
缺点是:常驻内存,不会被GC回收(普通类型需要的时候就初始化,用完被GC自动回收),而且过多使用单例,而单例类本身带有公有变量,就会很容易造成严重的问题