单例模式
一、线程安全性的讲解
1、视频截图
2、线程安全性的代码
加不加临界区进行验证
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <afxwin.h> #include <iostream> #include <stdio.h> using namespace std; CRITICAL_SECTION g_cs; class Singleton { private: Singleton() { m_singer = NULL; //cout << "构造一个Singleton对象" << endl; } public: static Singleton* getInstance() { //懒汉式:延迟加载 if (m_singer == NULL) { ::EnterCriticalSection(&g_cs); if(m_singer == NULL) m_singer = new Singleton; ::LeaveCriticalSection(&g_cs); } return m_singer; } private: static Singleton* m_singer; }; UINT Func(LPVOID lpParam) { int *i = (int*) lpParam; printf("%d--%x\n",*i, Singleton::getInstance()); return 0; } Singleton *Singleton::m_singer = NULL;//new Singleton; 在C++中构造函数不是线程安全的 int main(void) { //Singleton *p = new Singleton; //Singleton* p1 = Singleton::getInstance(); //Singleton* p2 = Singleton::getInstance(); //printf("p1=%x,p2=%x", p1, p2); ::InitializeCriticalSection(&g_cs); for (int i = 0;i < 10;i++) { //CreateThread(Func,&i); //HANDLE hThread = CreateThread(NULL, 0, Func, &i, 0, NULL); //CloseHandle(hThread); AfxBeginThread(Func, &i); } ::DeleteCriticalSection(&g_cs); system("pause"); return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
////回避多线程的安全问题 #include <afxwin.h> #include <stdio.h> #include <iostream> #include <map> using namespace std; class Singleton; static std::map<string, Singleton*> myMap = std::map<string, Singleton*>(); //懒汉-延迟加载 class Singleton { private: Singleton() { m_singer = NULL; //cout << "单例正在构建" << endl; } public: static Singleton* getInstance() { //std::map<std::string, int>::iterator it = myMap.find(DEFAULT_KEY); if (myMap.find(DEFAULT_KEY) != myMap.end()) return myMap.find(DEFAULT_KEY)->second; if (m_singer == NULL) { m_singer = new Singleton; myMap[DEFAULT_KEY] = m_singer; } return m_singer; } private: static Singleton *m_singer; static string DEFAULT_KEY; }; Singleton *Singleton::m_singer = NULL; string Singleton::DEFAULT_KEY = "One"; UINT Func(LPVOID lpParam) { int *i = (int*) lpParam; printf("%d--%x\n",*i, Singleton::getInstance()); return 0; } int main() { /*Singleton* p1 = Singleton::getInstance(); Singleton* p2 = Singleton::getInstance(); printf("p1's addr=%x,p2's addr=%x\n", p1, p2);*/ for (int i = 0; i < 10; i++) { AfxBeginThread(Func, &i); } system("pause"); return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <string> #include <stdio.h> #include <map> #include <iostream> using namespace std; //缓存的实例个数 const static int NUM_MAX = 5; class Singleton; static std::map<int, Singleton*> myMap = std::map<int, Singleton*>(); class Singleton { private: Singleton() { m_singer = NULL; cout << "正在构建Single" << endl; } public: static Singleton* getInstance() { m_singer = myMap[m_InstanceCount]; if (m_singer == NULL) { m_singer = new Singleton; myMap[m_InstanceCount] = m_singer; } m_InstanceCount++; if (m_InstanceCount > NUM_MAX) { m_InstanceCount = 1; } return m_singer; } private: static Singleton *m_singer; static int m_InstanceCount;//存放实例的个数 }; Singleton *Singleton::m_singer = NULL; int Singleton::m_InstanceCount = 1;//初始化的实例个数 int main() { Singleton* p1 = Singleton::getInstance(); Singleton* p2 = Singleton::getInstance(); Singleton* p3 = Singleton::getInstance(); Singleton* p4 = Singleton::getInstance(); Singleton* p5 = Singleton::getInstance(); printf("p1=%x,p2=%x,p3=%x,p4=%x,p5=%x\n", p1, p2, p3, p4, p5); Singleton* p6 = Singleton::getInstance(); Singleton* p7 = Singleton::getInstance(); Singleton* p8 = Singleton::getInstance(); Singleton* p9= Singleton::getInstance(); Singleton* p10 = Singleton::getInstance(); printf("p6=%x,p7=%x,p8=%x,p9=%x,p10=%x\n", p6, p7, p8, p9, p10); system("pause"); return 0; }