餓漢式單例與懶漢式單例的C 實現

2021-07-09 13:00:43 字數 2478 閱讀 5502

本文將介紹如何使用c#語言實現餓

漢式單例與懶

漢式單例,並分析餓漢式單例與懶漢式單例的優缺點。

1. 餓漢式單例類

餓漢式單例類(eager singleton)

是實現起來最容易的單例類,餓漢式單例類結構圖如圖1所示。

圖1 餓漢式單例類圖

從圖1中可以看出,由於在定義靜態變數的時候例項化單例類,因此在類載入時單例物件就已建立,**如下:

[csharp]view plain

copy

class

eagersingleton   

public

static

eagersingleton getinstance()   

}  當類被載入時,靜態變數instance 會被初始化,此時類的私有建構函式會被呼叫,單例類的唯一例項將被建立。

2.

懶漢式單例類與雙重檢查鎖定

與餓漢式單例類相同之處是,懶漢式單例類(lazy singleton)

的建構函式也是私有的。與餓漢式單例類不同的是,懶漢式單例類在第一次被引用時將自己例項化,在懶漢式單例類被載入時不會將自己例項化。懶漢式單例類結構圖如圖2所示。

圖2 懶漢式單例類圖

從圖2可以看出,在懶漢式單例類中,不是在定義靜態變數時例項化單例類,而是在第一次呼叫靜態工廠方法時例項化單例類。

但是懶漢式單例存在乙個很嚴重的問題:如果在高併發、多執行緒環境下實現懶漢式單例類,在某一時刻可能會有多個執行緒需要使用單例物件,即會有多個執行緒同時呼叫getinstance()方法,可能會造成建立多個例項物件,這將違背單例模式的設計意圖。為了防止生成多個單例物件,需要使用c#語言中的lock關鍵字lock關鍵字鎖定的**片段稱之為臨界區,可以確保當乙個執行緒位於**的臨界區時,另乙個執行緒不能進入臨界區。如果其他執行緒試圖進入鎖定的**,則將一直等待,直到該物件被釋放為止。修改之後的懶漢式單例類**如下:

[csharp]view plain

copy

class

lazysingleton   

public

static

lazysingleton getinstance()   

}  }  return

instance;   

}  }  

在上面給出的懶漢式單例類實現**中,對靜態工廠方法getinstance()中建立單例物件的**進行了加鎖,由於在呼叫時無法確定該單例物件是否已建立,因此需要使用輔助物件syncroot

來進行**鎖定。為了不影響程式的效能,此處只鎖定建立單例物件的**,並未鎖定整個方法。如果例項存在則直接返回,如果例項未建立則加鎖後再建立。

為了更好地對單例物件的建立進行控制,此處使用了一種被稱之為雙重檢查鎖定(double-checklocking)

的雙重判斷機制。在雙重檢查鎖定中,當例項不存在且同時有兩個執行緒呼叫getinstance()方法時,它們都可以通過第一重「instance==null」判斷,然後由於lock鎖定機制,只有乙個執行緒進入lock中執行建立**,另乙個執行緒處於排隊等待狀態,必須等待第乙個執行緒執行完畢後才可以進入lock鎖定的**,如果此時不進行第二重「instance==null」判斷,第二個執行緒並不知道例項已經建立,將繼續建立新的例項,還是會產生多個單例物件,違背單例模式的設計思想,因此需要進行雙重檢查。

3.

餓漢式單例類與懶漢式單例模擬較

餓漢式單例類在類被載入時就將自己例項化,它的優點在於無須考慮多個執行緒同時訪問的問題,可以確保例項的唯一性;從呼叫速度和反應時間角度來講,由於單例物件一開始就得以建立,因此要優於懶漢式單例。但是無論系統在執行時是否需要使用該單例物件,由於在類載入時該物件就需要建立,因此從資源利用效率角度來講,餓漢式單例不及懶漢式單例,而且在系統載入時由於需要建立餓漢式單例物件,載入時間可能會比較長。

懶漢式單例類在第一次使用時建立,無須一直占用系統資源,實現了延遲載入,但是必須處理好多個執行緒同時訪問的問題,特別是當單例類作為資源控制器,在例項化時必然涉及資源初始化,而資源初始化很有可能耗費大量時間,這意味著出現多執行緒同時首次引用此類的機率變得較大,需要通過雙重檢查鎖定等機制進行控制,這將導致系統效能受到一定影響。

單例(懶漢式單例 餓漢式單例)

public class singleton private static singleton instance new singleton public static singleton getinstance public class singleton public static synchr...

餓漢式單例和懶漢式單例

當我們想要乙個類只產生乙個例項化物件時,就需要用到單例模式,單例設計模式分為兩種 餓漢式和懶漢式。1 餓漢式單例 當用到這個類時,不管是否需要乙個物件都會建立乙個例項化物件 public class singleton public static singleton getinstance publ...

c 實現單例模式 懶漢式,餓漢式

這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。這種模式涉及到乙個單一的類,該類負責建立自己的物件,同時確保只有單個物件被建立。這個類提供了一種訪問其唯一的物件的方式,可以直接訪問,不需要例項化該類的物件。include include define barrier asm vol...