1. 程式人生 > >單例模式(懶漢式和餓漢式)及如何實現執行緒安全

單例模式(懶漢式和餓漢式)及如何實現執行緒安全

單例模式有兩種:懶漢式和餓漢式。

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