試想一下,如果有多執行緒的情況下,兩種單例模式是否安全?是否會出現建立多個例項的情況呢?下面先來看一下餓漢方式的單例模式,在此之前,我再把餓漢方式的實現**拷貝過來,有助於分析。
#include
using
namespace std;
class
config
private
:static config* temp;
public:~
config()
void
readconfig()
void
writeconfig()
public
:static config*
getinstance()
};config* config::temp =
newconfig()
;//建立例項
intmain()
很明顯,餓漢是執行緒安全的。因為餓漢模式下例項很早就建立了,假設在main中建立了兩個執行緒去獲取例項,兩個執行緒返回的例項都會是最早建立的那個例項,因此不存在會建立多個例項的情況。
再來看一下懶漢方式下的執行緒安全,同樣的,先拷貝乙份懶漢模式的**以便分析。
#include
using
namespace std;
class
config
private
:static config* temp;
public:~
config()
void
readconfig()
void
writeconfig()
public
:static config*
getinstance()
};config* config::temp =
null
;int
main()
我們假設有兩個執行緒需要獲取config的例項。當執行緒1呼叫getinstance(),並且判斷temp == null為真,因為此時還沒有例項,此時切到執行緒2也同樣呼叫了getinstance(),並且也判斷了temp== null為真,然後執行緒2建立了乙個例項,再切回到了執行緒1 ,這樣執行緒1也建立了例項,可以看出在兩個執行緒下,懶漢有肯能會建立兩個例項。
如何避免這種情況呢?也很簡單,加鎖就可以了,鎖是常用的使執行緒同步的一種方式。
#include
#include
using
namespace std;
class
config
public:~
config()
void
readconfig()
void
writeconfig()
public
:static config*
getinstance()
};config* config::temp =
null
;pthread_mutex_t config::mutex;
intmain()
互斥鎖是比較常用的一種鎖,在訪問全域性變數時之前加鎖,訪問完之後解鎖,這樣可以保證多執行緒中的全域性變數是同步的。採用上述加鎖的**之後,我們再來分析一下兩個執行緒的情況。
首先執行緒1呼叫getinstance()函式並且對mutex加鎖,判斷temp == null為真,進入條件語句中,此時切到執行緒2,也呼叫getinstance()函式,由於mutex已經被執行緒1鎖定,執行緒2不持有mutex,所以執行緒2會阻塞pthread_mutex_lock這個函式中,然後又切回到執行緒1,執行緒1建立了乙個單例的例項,並且解鎖,再切回到執行緒2,執行緒2給mutex加鎖,再判斷temp == null,這個條件為假,因為temp的值已經被執行緒1給賦值了,所以直接返回了temp,即執行緒1建立的例項,再解鎖。這樣就滿足了在多執行緒的情況下也不會建立多個例項,滿足單例模式的設計思想。
C 單例模式 與執行緒安全
單例模式 作為物件的建立模式,單例模式確保某乙個類只有乙個例項,而且自行例項化並向整個系統提供這個例項。這個類稱為單例類。單例模式的要點有三個 一是某個類只能有乙個例項 二是它必須自行建立這個例項 三是它必須自行向整個系統提供這個例項。在下面 的物件圖中,有乙個 單例物件 而 客戶甲 客戶乙 和 客...
C 單例模式與執行緒安全
1.教科書裡的單例模式 我們都很清楚乙個簡單的單例模式該怎樣去實現 建構函式宣告為private或protect防止被外部函式例項化,內部儲存乙個private static的類指標儲存唯一的例項,例項的動作由乙個public的類方法代勞,該方法也返回單例類唯一的例項。上 class singlet...
c 多執行緒單例模式 執行緒安全C 單例模式
我對此處記錄的單例模式有一些疑問 http us library ff650316.aspx 以下 摘自該文章 using system public sealed class singleton private static volatile singleton instance private ...