單例模式(懶漢式和餓漢式)及如何實現執行緒安全
阿新 • • 發佈:2019-01-05
單例模式有兩種:懶漢式和餓漢式。
1 #include <iostream> 2 3 using namespace std; 4 5 6 // 保證在整個程式執行期間,最多隻能有一個物件例項 7 8 9 // 懶漢式 10 // 1 、建構函式私有化 11 // 2 、寫一個靜態函式獲取物件指標 12 // 3 、有一個靜態成員變數,儲存物件指標 13 class Singleton 14 { 15 private: 16 Singleton() 17 { 18 19 } 20 21 public: 22 static Singleton* GetInstance() 23 { 24 if (m_instance == NULL) 25 m_instance = new Singleton; 26 27 return m_instance; 28 } 29 30 private: 31 static Singleton *m_instance; 32 }; 33 34 Singleton *Singleton::m_instance = NULL; 35 36 int main1() 37 { 38 Singleton* pa = Singleton::GetInstance(); 39 Singleton* pb = Singleton::GetInstance(); 40 Singleton* pc = Singleton::GetInstance(); 41 42 printf("%p\n", pa); 43 printf("%p\n", pb); 44 printf("%p\n", pc); 45 46 return 0; 47 } 48 49 50 // 惡漢式 51 class Singleton1 52 { 53 private: 54 Singleton1() 55 { 56 57 } 58 59 public: 60 static Singleton1* GetInstance() 61 { 62 return m_instance; 63 } 64 65 private: 66 static Singleton1 *m_instance; 67 }; 68 Singleton1 *Singleton1::m_instance = new Singleton1; 69 70 int main() 71 { 72 Singleton1* pa = Singleton1::GetInstance(); 73 Singleton1* pb = Singleton1::GetInstance(); 74 Singleton1* pc = Singleton1::GetInstance(); 75 76 printf("%p\n", pa); 77 printf("%p\n", pb); 78 printf("%p\n", pc); 79 80 return 0; 81 } 82
餓漢式因為物件已經初始化了,所以執行緒不會誤操作,但是懶漢式如何多個執行緒同時呼叫構造,如何實現執行緒安全呢?
1#include <iostream> 2 #include <pthread.h> 3 using namespace std; 4 5 class Singleton 6 { 7 private: 8 Singleton() 9 { 10 sleep(5); 11 printf (" 建構函式被呼叫 \n"); 12 } 13 14 public: 15 static Singleton* GetInstance() 16 { 17 // printf (" 獲取物件 \n"); 18 19 if (m_instance == NULL) 20 { 21 pthread_mutex_lock(&m_lock); // 上鎖 22 23 if (m_instance == NULL) 24 m_instance = new Singleton; 25 26 pthread_mutex_unlock(&m_lock); // 解鎖 27 } 28 29 return m_instance; 30 } 31 32 private: 33 static pthread_mutex_t m_lock; // 互斥鎖 34 static Singleton *m_instance; 35 }; 36 Singleton *Singleton::m_instance = NULL; 37 pthread_mutex_t Singleton::m_lock = PTHREAD_MUTEX_INITIALIZER; 38 39 40 41 void *worker(void* arg) 42 { 43 Singleton* p = Singleton::GetInstance(); 44 } 45 46 int main() 47 { 48 for (int i = 0; i < 10; i++) 49 { 50 pthread_t id; 51 pthread_create(&id, NULL, worker, NULL); 52 pthread_detach(id); // 執行緒分離 53 } 54 55 pthread_exit(NULL); 56 57 return 0; 58 } 59 60