您的位置:首页 > 编程语言 > C语言/C++

设计模式--单例模式Singleton(创建型)

2016-09-18 12:15 423 查看

单例模式Singleton背景

软件实现中,有些时候整个系统只需要拥有一个全局对象,这样有利于协调系统的整体行为,使系统在单个对象存在时更有效率,或者限制实例化为特定数量的对象。例如对某个协议栈模块的访问, 需要整个模块有且仅有一个访问入口,否则将会导致协议栈状态混乱,为此需要实现创建管理一个全局管理对象,维持其生命周期。

在软件工程中,单例模式提供了这样一个实现,保证了一个类只有一个实例存在,并提供一个访问它的全局访问点。

通过情况下,我们可以使用全局变量使得一个对象被全局访问,但该方法不能防止实例化多个对象,无法保证实例唯一性,一个最好的办法是,让类自身负责保护它的唯一实例,这个类可以保证没有其它实例被创建,并且提供一个访问该实例的方法,实现类实例的唯一性和受控访问。

单例模式Singleton实现

单例模式一个经典的实现方式:

class Singleton
{
private:
Singleton(){
//private constructor, 阻止外部调用new对象
}
Singleton(const Singleton&){
//private copy constructor, 防止被复制
};
Singleton& operator=(const Singleton&){
//private operator =, 防止被复制
};

private:
static Singleton *m_pInstance;

public:
static Singleton* GetInstance()  //本类实例全局唯一访问点
{
if(NULL == m_pInstance)
m_pInstance = new Singleton();

return m_pInstance;
}

static void DestoryInstance()
{
if (m_pInstance != NULL )
{
delete m_pInstance;
m_pInstance = NULL ;
}
}

// Other methods...
};


Singleton class通过将类的构造函数、复制构造函数以及赋值函数限定为private,避免了类在外部被实例化,其唯一实例只能通过GetInstance()方法访问。

多线程环境单例模式Singleton

上述单例模式实现代码直观易懂,但没有考虑线程安全问题,在多线程的运行环境中,当多个线程同时访问Singletion类的GetInstance()方法时,极有可能造成创建多个实例。若线程A运行检测到m_pInstance == NULL, 但来得及执行m_pInstance = new Singleton()时被线程B中断,线程B 执行同样的判断m_pInstance == NULL 从而创建了类的实例,当线程A再次获得运行权时,将继续执行创建类实例的操作,再次创建了实例,从而创建了多个实例,违背单例模式的初衷。因此比较直接的做法是,在创建实例时加锁lock,lock 确保当线程A位于代码lock保护区域时,其余线程不能进入该lock保护区域,此时若其它线程试图进入lock 保护区域,那么它将一直被阻塞等待,直到锁对象被释放。

static Singleton* GetInstance()  //本类实例全局唯一访问点
{
lock();   //TODO: 借用其它类来实现, std::mutex
{
if(NULL == m_pInstance)
m_pInstance = new Singleton();
}

return m_pInstance;
}


这种实现方式的确保证了单例模式的线程安全,确保对象创建的唯一性,但每次调用GetInstance 获取对象都需要lock 后判断, 对性能有较大影响, 一种改进的做法是,先判断对象是否已经创建,在未创建的情况下再加锁创建, 确保创建的唯一性。

static Singleton GetInstance() //本类实例全局唯一访问点
{

if(NULL == m_pInstance)
{
lock(); //TODO: 借用其它类来实现, std::mutex
{
if(null == m_pInstance)
m_pInstance = new Singleton();
}
}

return m_pInstance;
}


这种方式实现了在每次访问GetInstance 时仅仅在对象不存在时需要加锁lock,大大提高了效率。

说明: 单例模式有多种实现方式,文中只实现了其中的一种,逐步分析提供了在多线程环境中的安全机制。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计模式 singleton C++