單例模式實現

2021-10-01 01:38:22 字數 2340 閱讀 2838

什麼是設計模式

設計模式(design pattern)是一套被反覆使用、多數人知曉的、經過分類的、**設計經驗的總結

使用設計模式的目的:為了**可重用性、讓**更容易被他人理解、保證**可靠性

什麼是單例模式

單例模式是設計模式的一種,也是最簡單的一種,在單例模式中乙個類只能建立乙個例項,這種設計模式可以保證乙個類只有乙個例項,並提供乙個全域性的對外訪問點,該例項被所有其他模組共享。

餓漢方式實現單例模式

餓漢方式的特點是,不管將來用不用,一旦程式啟動就建立類的唯一例項。這樣帶來的問題是:如果需要建立的例項太多,將會導致程式啟動速度慢,並且不能確定每乙個例項的建立順序

#include

class

singleton

;//在類宣告時建立唯一例項

static singleton* instance;

public

://獲取唯一的例項

static singleton*

getinstance()

};singleton* singleton::instance =

newsingleton()

;

懶漢方式實現單例模式

啟動程式時不建立例項,當第一次需要使用該例項時再建立,這種方式相對於餓漢方式開機啟動速度更快,適用於物件構造十分耗費資源和時間,並且構造出來可能並不到的場景

class

singleton

static singleton* instance;

public

://獲取唯一的例項

static singleton*

getinstance()

return instance;}}

;singleton* singleton::instance =

nullptr

;

執行緒安全的懶漢實現方式

懶漢實現的單例模式存在著執行緒安全的問題,如果多個執行緒同時呼叫函式建立這個類物件時就可能出現建立了連個單例物件的情況。

例如:執行緒a和b同時都呼叫getinstance()建立單例物件,a判斷if條件為真進入條件語句,此時剛好時間a的時間片到了,輪到執行緒b,執行緒b也判斷if條件語句並為真進入條件語句(執行緒a還沒有建立物件因此instance依舊為空),此時將會建立兩個例項物件。

寫**的注意事項:

雙重判斷,降低鎖衝突的概率,提高效能,最外層的判斷條件是為了防止當例項物件已經被建立時,如果有執行緒試圖建立例項帶來的加鎖開銷。

volatile阻止編譯器優化,雙重判斷造成了未初始化的物件被呼叫

原因:編譯器優化(重排序)

#4 行**可以拆分為為三步:

memory = allocate();  // 1:分配物件的記憶體空間

ctorinstance(memory);  // 2:初始化物件

instance = memory;   // 3:設定instance指向剛分配的記憶體位址

編譯器經過優化,重排序後為

memory = allocate();  // 1:分配物件的記憶體空間

instance = memory;   // 3:設定instance指向剛分配的記憶體位址

// 注意,此時物件還沒有被初始化!

ctorinstance(memory); // 2:初始化物件

分析:

執行緒 a 執行了 #1 #2 #3 和 #4 的前兩部(優化後的),時間片輪轉到執行緒 b

執行緒 b 判斷 #1 不為空,將對乙個未初始化的變數進行操作

解決:用 volatile 修飾,可以防止編譯器優化,解決問題

class

singleton

pthread_mutex_unlock

(&_mutex)

;// #5

}return instance;

}private

:singleton()

//volatile 防止編譯器優化,造成呼叫未初始化的物件

static singleton*

volatile instance;

static pthread_mutex_t _mutex;};

singleton*

volatile singleton::instance =

nullptr

;pthread_mutex_t singleton::_mutex;

單例模式實現

單例模式 singleton 保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點。1 適用於單執行緒 class singleton public static singleton getinstance return instance 註解 singleton的靜態屬性instance中,只有...

單例模式實現

推薦的單例實現方法 餓漢模式 1種 public class singleton public static singleton getinstance 雙重檢查 volatile關鍵字必須加 public class singleton public static singleton getins...

單例模式實現

單例模式分為餓漢式和懶漢式 實現 餓漢式 所謂餓漢式,也就是不管能不能用的上,都會載入,像乙個惡漢,如果在構造方法裡寫了效能消耗較大,佔時較久的 比如建立與資料庫的連線,那麼就會在啟動的時候感覺稍微有些卡頓。private singleton1 private static singleton1 i...