单例模式

一、线程安全性的讲解

1、视频截图

 2、线程安全性的代码

加不加临界区进行验证

#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;
}
临界区模式
////回避多线程的安全问题
#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;
}
缓存与单例
#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;
}
多例扩展

 

posted @ 2023-04-28 09:54  泽良_小涛  阅读(8)  评论(0编辑  收藏  举报