博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计一个线程安全的单例(Singleton)模式
阅读量:5115 次
发布时间:2019-06-13

本文共 1998 字,大约阅读时间需要 6 分钟。

       在设计单例模式的时候。尽管非常easy设计出符合单例模式原则的类类型,可是考虑到垃圾回收机制以及线程安全性。须要我们思考的很多其它。有些设计尽管能够勉强满足项目要求,可是在进行多线程设计的时候。不考虑线程安全性。必定会给我们的程序设计带来隐患。此处。我们不介绍什么是单例模式,也不介绍怎样设计简单的设计模式,由于你全然能够在书上或者在博客中找到。

此处我们的目的就是设计一个使用的单例模式类。单例模式须要注意与思考的问题:

(1)怎样仅能实例化一个对象?

(2)怎么样设计垃圾回收机制?

(3)怎样确保线程安全性?

      在思考了上述的几个问题后,首先设计一个线程安全的类。注意:由于CResGuard类会被多个线程訪问。所以这个类除了构造函数与析构函数意外。其它成员都是线程安全的。

class CResGuard {public:	CResGuard()  { m_lGrdCnt = 0; InitializeCriticalSection(&m_cs); }	~CResGuard() { DeleteCriticalSection(&m_cs); }	// IsGuarded 用于调试	BOOL IsGuarded() const { return(m_lGrdCnt > 0); }public:	class CGuard {	public:		CGuard(CResGuard& rg) : m_rg(rg) { m_rg.Guard(); };		~CGuard() { m_rg.Unguard(); }	private:		CResGuard& m_rg;	};private:	void Guard()   { EnterCriticalSection(&m_cs); m_lGrdCnt++; }	void Unguard() { m_lGrdCnt--; LeaveCriticalSection(&m_cs); }	// Guard/Unguard两个方法仅仅能被内嵌类CGuard訪问.	friend class CResGuard::CGuard;private:	CRITICAL_SECTION m_cs;	long m_lGrdCnt;   };

       接下来我们须要设计一个符合上面三个条件的类。为了实现自己主动回收机制,我们使用了智能指针auto_ptr,尽管非常多人不喜欢它,原因是使用不当。会产生不少陷阱。所以你全然能够用其它智能指针替代它。

为了方便未来的使用,还使用了模版。假设你不喜欢。能够花两分钟的时间轻松的干掉它。

namespace Pattern	{		template 
class Singleton { public: static inline T* instance(); private: Singleton(void){} ~Singleton(void){} Singleton(const Singleton&){} Singleton & operator= (const Singleton &){} static auto_ptr
_instance; static CResGuard _rs; }; template
auto_ptr
Singleton
::_instance; template
CResGuard Singleton
::_rs; template
inline T* Singleton
::instance() { if (0 == _instance.get()) { CResGuard::CGuard gd(_rs); if (0 == _instance.get()) { _instance.reset(new T); } } return _instance.get(); }//实现单例模式的类的地方。必须将宏定义放在声明文件里,#define DECLARE_SINGLETON_CLASS( type ) \ friend class auto_ptr< type >; \ friend class Singleton< type >; }
单例我们尽管看似简单,可是有太多问题非常值得我们思考与深究。由于一定程度上,它深入到了C++语言机制,更能够加深你对此语言设计的理解程度。

转载于:https://www.cnblogs.com/jhcelue/p/7242164.html

你可能感兴趣的文章
区分汉字与英文
查看>>
div常用效果方法-transform
查看>>
js 的函数参数的默认值问题
查看>>
this.$router.push、replace、go的区别
查看>>
冲刺9
查看>>
VS2013搭建wxWidgets开发环境
查看>>
JS——构造函数、原型与实例之间的关系 及 原型链 的描述
查看>>
Sql Server实现自动增长
查看>>
继承(引用~析构~virtual)
查看>>
JAVA如何插入MySql的datetime类型
查看>>
python全栈开发-Day11 迭代器、生成器、面向过程编程
查看>>
BoxandUnbox.cs
查看>>
Linux 内核 3.8 是给 Linux 用户的圣诞礼物
查看>>
Hibernate Search v.4.2.0.CR1 发布
查看>>
css渐变圆角参考
查看>>
拦截器 参数不过去 的解决方法
查看>>
JS 选项卡
查看>>
mina 和 xsocket
查看>>
PyQt5-多窗口数据传输
查看>>
011 aware
查看>>