日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

设计模式的理解:单例模式(Singleton)

發(fā)布時間:2024/10/14 asp.net 130 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式的理解:单例模式(Singleton) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

單例模式使用的目的是 ①一個類只能初始化出一個對象?②保證對象是線程安全的。

其做法:

1、將 構(gòu)造函數(shù) 和拷貝構(gòu)造函數(shù) 設(shè)置為私有 并將自身類的指針設(shè)置成靜態(tài)成員,其函數(shù)方法也設(shè)置成靜態(tài)方法。保證該類只創(chuàng)建一個對象

2、通過加鎖的方式,對 對象訪問加以限制

class Singleton { private:static Singleton * instance; Singleton (){} Singleton(const Singleton& other);public:static Singleton* getInstance() { if (instance == nullptr) { instance = new Singleton(); } return instance; } }

以上在單線程中是可以滿足一個類對象只會被初始化一次的條件。但是在多線程中 假如其中一個線程在執(zhí)行? ?instance = new Singleton();? ?語句前,而另外一個剛好進(jìn)入 if 語句時,這個類就會被初始化兩次。所以上述的編碼方式時線程不安全的。

二、雙重加鎖

class Singleton { private:static Singleton * instance; Singleton (){} Singleton(const Singleton& other);public:static Singleton* getInstance() { if (instance == nullptr) { Lock lock;if(instance == nullptr){instance = new Singleton(); }} return instance; } }

上述代碼是雙重鎖機制,當(dāng)一個線程先獲取到鎖的時候,第二個線程讀鎖時就會等待第一個鎖初始化完對象后才繼續(xù)執(zhí)行。但是上述寫法沒有考慮到內(nèi)存讀寫reorder不安全。

正常創(chuàng)建對象實例會走三步驟

1) 分配對象內(nèi)存

2) 調(diào)用構(gòu)造器,執(zhí)行初始化

3) 將對象的引用賦值給變量。

然而在編譯器優(yōu)化等問題下,在實際可能的運行順序是,先執(zhí)行第三步再執(zhí)行第二部,即先引用給對象再調(diào)用構(gòu)造器。

如果

假如其中一個線程在執(zhí)行? ?instance = new Singleton();? ?語句時,分配完了內(nèi)存,將對象將對象的引用賦值給變量,此時第二個線程判斷 if (instance == nullptr) 不成立直接返回了一個還未初始化完的對象。那么就會造成線程不安全。這個創(chuàng)建對象的二三步驟亂序執(zhí)行實際上叫重排序。

在JAVA ,C#中 ,新增了一個關(guān)鍵字volatile,在聲明成員變量時??volatile static Singleton instance;? ? 表示禁止?instance創(chuàng)建對象時重排序。

而在C++ 11版本的跨平臺實現(xiàn)

//C++ 11版本之后的跨平臺實現(xiàn) // atomic c++11中提供的原子操作 std::atomic<Singleton*> Singleton::m_instance; std::mutex Singleton::m_mutex;/* * std::atomic_thread_fence(std::memory_order_acquire); * std::atomic_thread_fence(std::memory_order_release); * 這兩句話可以保證他們之間的語句不會發(fā)生亂序執(zhí)行。 */ Singleton* Singleton::getInstance() {Singleton* tmp = m_instance.load(std::memory_order_relaxed);std::atomic_thread_fence(std::memory_order_acquire);//獲取內(nèi)存fenceif (tmp == nullptr) {std::lock_guard<std::mutex> lock(m_mutex);tmp = m_instance.load(std::memory_order_relaxed);if (tmp == nullptr) {tmp = new Singleton;std::atomic_thread_fence(std::memory_order_release);//釋放內(nèi)存fencem_instance.store(tmp, std::memory_order_relaxed);}}return tmp; }

?

或者有更簡潔的C++寫法,但在C++11版本前不支持。

class Singleton{ public:// 注意返回的是引用。static Singleton& getInstance(){static Singleton m_instance; //局部靜態(tài)變量return m_instance;} private:Singleton(); //私有構(gòu)造函數(shù),不允許使用者自己生成對象Singleton(const Singleton& other); };

?

?

?

?

?

?

總結(jié)

以上是生活随笔為你收集整理的设计模式的理解:单例模式(Singleton)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。