加锁懒汉式
懒汉:在第一次用到类实例的时候才会去实例化。
在访问量较小时,采用懒汉实现。这是以时间换空间。(注意,懒汉本身是线程不安全的)
#include <iostream>
#include<mutex>
#include<thread>
using namespace std;
std::mutex mtx;
class CSingleton {
private:
CSingleton() {};
static CSingleton *instance;
public:
static CSingleton *Instance();
};
CSingleton *CSingleton::instance = nullptr;
CSingleton *CSingleton::Instance() {
if (instance == NULL)
{
mtx.lock();
if (instance == NULL) {
instance = new CSingleton();
}
mtx.unlock();
}
return instance;
};
int main()
{
CSingleton *inst = CSingleton::Instance();
cout << "Hello World" << endl;
system("pause");
return 0;
}
#include <iostream>
#include <process.h>
#include <windows.h>
using namespace std;
class Singelton {
private:
Singelton() {
m_count++;
printf("Singelton begin\n");
Sleep(1000); // 加sleep为了放大效果
printf("Singelton end\n");
}
static Singelton *single;
public:
static Singelton *GetSingelton();
static void print();
static int m_count;
};
Singelton *Singelton::single = nullptr;
int Singelton::m_count = 0;
Singelton *Singelton::GetSingelton() {
if (single == nullptr) {
single = new Singelton;
}
return single;
}
void Singelton::print() {
cout << m_count << endl;
}
// 回调函数
void threadFunc(void *p) {
DWORD id = GetCurrentThreadId(); // 获得线程id
cout << id << endl;
Singelton::GetSingelton()->print(); // 构造函数并获得实例,调用静态成员函数
}
int main(int argc, const char * argv[]) {
int threadNum = 3;
HANDLE threadHdl[100];
// 创建3个线程
for (int i = 0; i < threadNum; i++) {
threadHdl[i] = (HANDLE)_beginthread(threadFunc, 0, nullptr);
}
// 让主进程等待所有的线程结束后再退出
for (int i = 0; i < threadNum; i++) {
WaitForSingleObject(threadHdl[i], INFINITE);
}
cout << "main" << endl; // 验证主进程是否是最后退出
system("pause");
return 0;
}
饿汉:饿了肯定要饥不择食。所以在单例类定义的时候就进行实例化。(本身就是线程安全的,如下例子)
由于要进行线程同步,所以在访问量比较大,或者可能访问的线程比较多时,采用饿汉实现,可以实现更好的性能。这是以空间换时间。
#include <iostream>
#include <process.h>
#include <windows.h>
using namespace std;
class Singelton{
private:
Singelton(){
m_count ++;
printf("Singelton begin\n");
Sleep(1000); // 加sleep为了放大效果
printf("Singelton end\n");
}
static Singelton *single;
public:
static Singelton *GetSingelton();
static void print();
static int m_count;
};
// 饿汉模式的关键:初始化即实例化
Singelton *Singelton::single = new Singelton;
int Singelton::m_count = 0;
Singelton *Singelton::GetSingelton(){
// 不再需要进行实例化
//if(single == nullptr){
// single = new Singelton;
//}
return single;
}
void Singelton::print(){
cout<<m_count<<endl;
}
// 回调函数
void threadFunc(void *p){
DWORD id = GetCurrentThreadId(); // 获得线程id
cout<<id<<endl;
Singelton::GetSingelton()->print(); // 构造函数并获得实例,调用静态成员函数
}
int main(int argc, const char * argv[]) {
int threadNum = 3;
HANDLE threadHdl[100];
// 创建3个线程
for(int i = 0; i<threadNum; i++){
threadHdl[i] = (HANDLE)_beginthread(threadFunc, 0, nullptr);
}
// 让主进程等待所有的线程结束后再退出
for(int i = 0; i<threadNum; i++){
WaitForSingleObject(threadHdl[i], INFINITE);
}
cout<<"main"<<endl; // 验证主进程是否是最后退出
return 0;
}