單例模式是設計模式的最簡單的形式之一。這個模式的最主要目的是使得類的一個對象稱為系統中唯一的實例。
一個類只有一個對象。
例如:一夫一妻制。
我們可以考慮一下:我們在打游戲的時候,由于游戲資源非常的大,所以不可能一次性將所有的游戲數據加載到CPU上,有種“延時加載”的思想(懶漢模式)。反之,當在啟動時,將所需的資源準備好的,屬于“及時加載”的思想(餓漢模式)
c++單例模式。餓漢模式怎么實現創建對象時,立即分配資源呢?
用static關鍵字實現。
static關鍵字講解
template<class T>
class Single_Starve
{
public:static T *GetData(){return &_data;}
private:static T _data;
};
餓漢模式是線程安全的,在類的創建時同時實例化一個靜態的實例。
由于懶漢模式是在實際使用資源的時候才會主動申請資源。
template<class T>
class Singel_Slacker
{
public:static T *GetData(){_mutex.lock(); //加鎖操作if(_data == NULL)_data = new T();_mutex.unlock(); //解鎖操作return _data;}
private:volatile static T* _data; //這里只是申請了保存資源地址的空間static std::mutex _mutex; //調用mutex庫函數,定義鎖資源
};
volatile關鍵字:防止編譯器過度優化。
擔心編譯器對代碼進行優化,使得數據直接從寄存器中取,會造成數據邏輯混亂,所以使用volatile關鍵字。
單例模式是什么、由于懶漢模式是在使用資源的時候,才申請資源,所以會出現線程安全問題,因此在申請資源的時候,需要進行加鎖操作,申請完資源后,需要解鎖。
但是上面代碼有鎖沖突的概率
那什么是鎖沖突
當_data = NULL時,A線程運行時,先進行加鎖操作,這時B線程也過來了,等待鎖資源,當A操作完成后,現在_data 已經不為NULL,A釋放鎖資源,這時處于等待隊列中的線程B進行加鎖操作,加完鎖后發現_data已經不為NULL,則返回A申請的資源后才解鎖,這樣無用的操作,就會降低效率。
template<class T>
class Singel_Slacker
{
public:static T *GetData(){if(_data == NULL) //雙判斷,降低鎖沖突{_mutex.lock(); //加鎖操作if(_data == NULL)_data = new T();_mutex.unlock(); //解鎖操作}return _data;}
private:volatile static T* _data; //這里只是申請了保存資源地址的空間static std::mutex _mutex; //調用mutex庫函數,定義鎖資源
};
懶漢模式是延遲加載思想,面對多線程訪問的時候,需要進行加鎖操作,實現同步,為了增加效率,降低鎖沖突,則需要進行二次判斷
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态