把構造函數設爲私有函數以禁止他人建立。定義一個靜態實例,在須要的時候建立該實例。c#
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 }
只適合單線程,若是多線程同時運行到判斷語句,會建立多個實例。多線程
對第一種方法的改進,能夠經過添加一個同步鎖。函數
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; } } }
此時只有一個線程能夠獲得同步鎖。其餘的線程只能等待,等第一個線程執行完建立實例或獲得實例後,其餘線程再依次進行得到同步鎖和判斷。spa
第二種方法在每次線程都會執行同步鎖,而同步鎖是一個效率很低費時間的操做,因此要避免加鎖操做。
咱們在實例尚未建立前須要加鎖,以後就不須要加鎖操做了,進一步改進以下:線程
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; } } } }
在c#中,靜態構造函數只會被調用一次。能夠利用這一特性進行單例模式。code
public sealed class Singleton4 { private Singleton4(){ } private static Singleton4 instance = new Singleton4(); public static Singleton4 Instance { get{ return instance; } } }
public sealed class Singleton5 { Singleton5(){ } public static Singleton5 Instance{ get{ return Nested.instance; } } class Nested { static Nested(){ } internal static readonly Singleton5 instance = new Singleton5(); } }