国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

老生常談C++的單例模式與線程安全單例模式(懶漢/餓漢)

2020-05-23 13:57:41
字體:
供稿:網(wǎng)友

1 教科書里的單例模式

我們都很清楚一個簡單的單例模式該怎樣去實現(xiàn):構(gòu)造函數(shù)聲明為private或protect防止被外部函數(shù)實例化,內(nèi)部保存一個private static的類指針保存唯一的實例,實例的動作由一個public的類方法代勞,該方法也返回單例類唯一的實例。

上代碼: 

class singleton{protected:  singleton(){}private:  static singleton* p;public:  static singleton* instance();};singleton* singleton::p = NULL;singleton* singleton::instance(){  if (p == NULL)    p = new singleton();  return p;}

這是一個很棒的實現(xiàn),簡單易懂。但這是一個完美的實現(xiàn)嗎?不!該方法是線程不安全的,考慮兩個線程同時首次調(diào)用instance方法且同時檢測到p是NULL值,則兩個線程會同時構(gòu)造一個實例給p,這是嚴重的錯誤!同時,這也不是單例的唯一實現(xiàn)!

2 懶漢與餓漢

單例大約有兩種實現(xiàn)方法:懶漢與餓漢。

懶漢:故名思義,不到萬不得已就不會去實例化類,也就是說在第一次用到類實例的時候才會去實例化,所以上邊的經(jīng)典方法被歸為懶漢實現(xiàn);

餓漢:餓了肯定要饑不擇食。所以在單例類定義的時候就進行實例化。

特點與選擇:

由于要進行線程同步,所以在訪問量比較大,或者可能訪問的線程比較多時,采用餓漢實現(xiàn),可以實現(xiàn)更好的性能。這是以空間換時間。

在訪問量較小時,采用懶漢實現(xiàn)。這是以時間換空間。

3 線程安全的懶漢實現(xiàn)

線程不安全,怎么辦呢?最直觀的方法:加鎖。

方法1:加鎖的經(jīng)典懶漢實現(xiàn):

class singleton{protected:  singleton()  {    pthread_mutex_init(&mutex);  }private:  static singleton* p;public:  static pthread_mutex_t mutex;  static singleton* initance();};pthread_mutex_t singleton::mutex;singleton* singleton::p = NULL;singleton* singleton::initance(){  if (p == NULL)  {    pthread_mutex_lock(&mutex);    if (p == NULL)      p = new singleton();    pthread_mutex_unlock(&mutex);  }  return p;}

方法2:內(nèi)部靜態(tài)變量的懶漢實現(xiàn)

此方法也很容易實現(xiàn),在instance函數(shù)里定義一個靜態(tài)的實例,也可以保證擁有唯一實例,在返回時只需要返回其指針就可以了。推薦這種實現(xiàn)方法,真得非常簡單。

class singleton{protected:  singleton()  {    pthread_mutex_init(&mutex);  }public:  static pthread_mutex_t mutex;  static singleton* initance();  int a;};pthread_mutex_t singleton::mutex;singleton* singleton::initance(){  pthread_mutex_lock(&mutex);  static singleton obj;  pthread_mutex_unlock(&mutex);  return &obj;}

4 餓漢實現(xiàn)

為什么我不講“線程安全的餓漢實現(xiàn)”?因為餓漢實現(xiàn)本來就是線程安全的,不用加鎖。為啥?自己想!

class singleton{protected:  singleton()  {}private:  static singleton* p;public:  static singleton* initance();};singleton* singleton::p = new singleton;singleton* singleton::initance(){  return p;}

是不是特別簡單呢?

以空間換時間,你說簡單不簡單?

面試的時候,線程安全的單例模式怎么寫?肯定怎么簡單怎么寫呀!餓漢模式反而最懶[正經(jīng)臉]! 

以上就是小編為大家?guī)淼睦仙U凜++的單例模式與線程安全單例模式(懶漢/餓漢)全部內(nèi)容了,希望大家多多支持VEVB武林網(wǎng)~

 

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 万宁市| 北票市| 弋阳县| 高淳县| 雅江县| 武川县| 游戏| 昌邑市| 衡南县| 信阳市| 东光县| 庐江县| 咸丰县| 德阳市| 梁河县| 巴楚县| 津南区| 合作市| 应城市| 讷河市| 沙雅县| 建阳市| 黔西| 盐源县| 北宁市| 和田市| 乌拉特前旗| 镇原县| 通城县| 武隆县| 兴海县| 漠河县| 曲沃县| 垣曲县| 武安市| 泸水县| 舟曲县| 尼勒克县| 博罗县| 湘乡市| 永胜县|