单例模式--作用:
确保一个类中只有一个实例,并提供全局访问点;
特点:
1. 构造函数 私有化,因此不能直接定义一个该类的对象: private: Csingle(){};
2. 定义一个类型为 该类本身的指针 的一个静态成员 : static CSingleton* m_singleInstance;
3. 定义一个返回类型为 该类本身的指针 的一个静态成员函数:
static CSingleton* getSingleInstance(){
if(m_singleInstance == nullptr) m_singleInstance = new CSingleton;
return m_singleInstance;
}
4. 外部直接通过 CSingleton::getSingleInstance()函数来获取这唯一的实例;
单例模式与多线程
防止竞争的方法:
1. 多线程访问时,需要同步机制: 在进入getSingleInstance函数后加入互斥锁之类的内核对象来进行同步;
class CSingleton
{
public:
~CSingleton() {};
static CSingleton* m_sticSingleInstance;
static CSingleton* GetSingleInstance();
private:
CSingleton() {};
};
#include "CSingleton.h"
#include <boost/thread/mutex.hpp>
#include <boost/thread/lock_guard.hpp>
boost::mutex g_mutex;
CSingleton* CSingleton::m_sticSingleInstance = nullptr;
CSingleton* CSingleton::GetSingleInstance()
{
boost::lock_guard<boost::mutex> lock(g_mutex);//同步锁
if (m_sticSingleInstance == nullptr) {
m_sticSingleInstance = new CSingleton;
}
return m_sticSingleInstance;
}
2. 提前分配好m_singleInstance实例,在静态成员实例m_singleInstance初始化时就将实现 new CSingleton,而不是在getSingleInstance()函数中再创建实例对象;
#include "CSingleton.h"
//初始化就创建实例,不会创建有多个实例
CSingleton* CSingleton::m_sticSingleInstance = new CSingleton;
CSingleton* CSingleton::GetSingleInstance()
{
return m_sticSingleInstance;
}
3. double-checked locking,使用“双重检查锁”,volatile修饰静态成员m_singleInstance,在getSingleInstance函数中,先检查实例是否已创建,如果尚未创建,才进行同步; 这样,只有第一次时会有同步操作,后续使用getSingleInstance函数时不会有同步动作,减少消耗;
#include "CSingleton.h"
#include <boost/thread/mutex.hpp>
#include <boost/thread/lock_guard.hpp>
boost::mutex g_mutex;
CSingleton* CSingleton::m_sticSingleInstance = nullptr;
CSingleton* CSingleton::GetSingleInstance()
{
if (m_sticSingleInstance == nullptr) {
//判断是否为nullptr后再加锁
boost::unique_lock<boost::mutex> lock(g_mutex);
if (m_sticSingleInstance == nullptr) {
m_sticSingleInstance = new CSingleton;
}
lock.unlock();
}
return m_sticSingleInstance;
}