C++单例模式:单例模式遇到多线程
生活随笔
收集整理的這篇文章主要介紹了
C++单例模式:单例模式遇到多线程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
單例模式介紹
單例模式主要有2中形式,一種是餓漢式,一種是懶漢式。
餓漢式:程序一加載單例模式就已經創建了,也就很饑餓嘛。因為是靜態屬性進行單例初始化,所以優點是線程是安全的,缺點是無論用戶是否使用單例對象都會創建單例對象。
懶漢式:當用戶使用單例對象時,才去創建單例對象,所以很懶惰嘛。優點是用戶不使用就不會創建對象,缺點是 當遇到多線程是,是線程不安全的,但是我們可以使用加強版的也就是線程安全的懶漢式,下面我們會進行講解。
餓漢式和懶漢式代碼
代碼展示
#include <iostream>using namespace std; class Singleton_Hungry { private:Singleton_Hungry(){cout << "我是餓漢式,在程序加載時,我就已經存在了。" << endl;}static Singleton_Hungry* singleton; public:static Singleton_Hungry* getInstace(){return singleton;}}; //靜態屬性類外初始化 Singleton_Hungry* Singleton_Hungry::singleton = new Singleton_Hungry;class Singleton_Lazy { private:Singleton_Lazy(){cout << "我是懶漢式,在別人需要我的時候,我才現身。" << endl;}static Singleton_Lazy* singleton; public:static Singleton_Lazy* getInstance(){if (NULL == singleton){singleton = new Singleton_Lazy;}return singleton;} }; Singleton_Lazy* Singleton_Lazy::singleton = NULL;int main(int argc, char *argv[]) {Singleton_Hungry *hungry1 = Singleton_Hungry::getInstace();Singleton_Hungry *hungry2 = Singleton_Hungry::getInstace();cout << "hungry1地址:" << hungry1 << ",hungry2地址:" << hungry2 << endl;Singleton_Lazy *lazy1 = Singleton_Lazy::getInstance();Singleton_Lazy *lazy2 = Singleton_Lazy::getInstance();cout << "lazy1地址:" << lazy1 << ",lazy2地址:" << lazy1 << endl;return 0; }運行結果
懶漢式遇到多線程
由于懶漢式在用戶需要是才進行單例對象的創建,如果遇到多線程容易發生內存泄漏,我們可以用c++中的線程互斥對象mutex來進行加強。多線程用thread類進模擬。
代碼展示
#include <iostream> #include <mutex> #include <thread>using namespace std; mutex mu;//線程互斥對象 class Singleton_Hungry { private:Singleton_Hungry(){cout << "我是餓漢式,在程序加載時,我就已經存在了。" << endl;}static Singleton_Hungry* singleton; public:static Singleton_Hungry* getInstace(){return singleton;}}; //靜態屬性類外初始化 Singleton_Hungry* Singleton_Hungry::singleton = new Singleton_Hungry;class Singleton_Lazy { private:Singleton_Lazy(){cout << "我是懶漢式,在別人需要我的時候,我才現身。" << endl;}static Singleton_Lazy* singleton; public:static Singleton_Lazy* getInstance(){if (NULL == singleton){mu.lock();//關閉鎖if (NULL == singleton){singleton = new Singleton_Lazy;}mu.unlock();//打開鎖}return singleton;} }; Singleton_Lazy* Singleton_Lazy::singleton = NULL; void thread01() {for (int i = 0; i < 5; i++){cout << "thread01 working...." << endl;Singleton_Lazy *lazy1 = Singleton_Lazy::getInstance();cout << "thread01創建單例lazy1地址:" << lazy1 << endl;} } void thread02() {for (int i = 0; i < 5; i++){cout << "thread02 working...." << endl;Singleton_Lazy *lazy2 = Singleton_Lazy::getInstance();cout << "thread02創建單例lazy2地址:" << lazy2 << endl;} }int main(int argc, char *argv[]) {thread thread1(thread01);thread thread2(thread01);thread1.detach();thread2.detach();for (int i = 0; i < 5; i++){cout << "Main thread working..." << endl;Singleton_Lazy *main = Singleton_Lazy::getInstance();cout << "Main 創建單例lazy地址:" << main << endl;}return 0; }
多線程下線程不安全的懶漢式測試
下圖是將40行45行線程互斥對象操作注釋的情況,發生了內存泄漏,創建了多個單例。圖中字打錯了。。。
多線程下線程安全的懶漢式測試
總結
以上是生活随笔為你收集整理的C++单例模式:单例模式遇到多线程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 记一次性能调优
- 下一篇: Unable to instantiat