題目詳解:只能生成一個實例的類,,就是實現了singleton模式的類型
爲了達到只能生成一個實例的目的,我們必須把類的構造函數聲明爲私有來禁止其他人創建實例。
public sealed class Singleton
{
private Singleton()//把構造函數定義爲私有函數
{
}
private static object sycObj=new object();//設置同步鎖,預防多線程情況下,兩個線程同時創建實例,加上同步鎖之後,在一個時刻只有一個線程能得到同步鎖,另一個線程只能等待
private static Singleton instance=NULL;//只有在instance爲空時,才能創建一個實例避免重複創建。
public static Singleton Instance
{
get
{
if(instance==null)
{
lock(syncObj)
{
if(instance==null)
{
if(instance==null)
{
instance=new Singletion();
}
}
return instance;
}
}
}
當instance 爲null時,也就是還沒有創建時,需要進行加鎖操作,創建出來之後,則無需加鎖。這個解法使用加鎖機制來確保在多線程下只創建一個,實例,兩個if實現了比較好的效率。然後代碼稍微有點複雜,編寫代碼時容易出錯。
下面是比較優秀的解法
C#中靜態構造函數能夠確保只調用一次,利用好此方法,能夠以簡短的代碼來實現這個題目
public sealed class Singleton
{
private Singleton
{
}
private static Singleton instance=new Singleton();
public static Singleton Instance
{
get
{
return instance ;
}
}
}
在這個方法中,實例instance在第一次使用到Singleton時就會被創建,假設在singleton裏面添加一個靜態方法,調用該靜態方法是不用在創建一個實例的,
這個方法雖然簡單,但是,但是過早地創建實例。會讓內存使用效率降低。
下面介紹的這種方法,解決了上面過早創建實例的問題,實現了按需創建實例
public sealed class Singleton
{
Singleton
{
}
public static Singleton Instance
{
get
{
return Nested.instance;
}
}
class Nested
{
static Nested
{
}
internal static readonly Singleton instance =new Singleton();
}
}
只有當我們通過Singleton.Instance來得到Singleton 的實例時,纔會調用nested的靜態構造函數來創建實例instance,當我們不調用Singleton,Instance 時,nested不會被調用,也不會創建實例。
結論:第一種方法,兩次判斷和一次加鎖確保多線程下高效率的工作
第二種方法,利用C#靜態構造函數的特性,第三種方法利用私有嵌套類型的特性,按需創建,提高了空間使用效率。
PS:本人最近在複習相關的知識,看到相關的題目覺得值得分享,若有錯誤歡迎指正。