并发场景下的单例模式,需要加锁。
#pragma once
#include <mutex>
using namespace std;
class SingleInstance
{
public:
static SingleInstance *getInstance();
private:
SingleInstance() = default;
~ SingleInstance() = default;
private:
static SingleInstance * instance;
static mutex instanceLock;
};
一:简单粗暴的方式
#include "SingleInstance.h"
SingleInstance * SingleInstance::instance = nullptr;
mutex SingleInstance::instanceLock;
SingleInstance *SingleInstance::getInstance()
{
lock_guard<mutex> lk(instanceLock);
if (instance == nullptr) {
instance = new SingleInstance();
}
return instance;
}
入口处直接加锁,其实这样加锁,锁粒度有点大
二:最小粒度加锁
SingleInstance *SingleInstance::getInstance(){
if (instance == nullptr) {
lock_guard<mutex> lk(instanceLock);
if (instance == nullptr) {
instance = new SingleInstance();
}
}
return instance;
}
二者性能测试代码如下:
#include <iostream>
#include <string>
#include <map>
#include "LogTime.h"
#include "SingleInstance.h"
using namespace std;
int main(int argc, int * argv[])
{
LogTime time;
time.Start();
for (int i = 0; i < 1e5; i++) { // 获取单例1万次
SingleInstance::getInstance();
}
time.End();
cout << "run:" << time.GetRunTime() << endl;
system("pause");
}
测试结果如下:
方式一结果:
方式二结果:
可见:运行时间为32倍的差距。在性能要求较高的场景下,最小粒度实现的方式,明显性能更好。