设计一个线程安全的单例(Singleton)模式
在设计单例模式的时候。尽管非常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 T>
class Singleton
{
public:
static inline T* instance(); private:
Singleton(void){}
~Singleton(void){}
Singleton(const Singleton&){}
Singleton & operator= (const Singleton &){} static auto_ptr<T> _instance;
static CResGuard _rs;
}; template <class T>
auto_ptr<T> Singleton<T>::_instance; template <class T>
CResGuard Singleton<T>::_rs; template <class T>
inline T* Singleton<T>::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++语言机制,更能够加深你对此语言设计的理解程度。
设计一个线程安全的单例(Singleton)模式的更多相关文章
- 不使用synchronized和lock,如何实现一个线程安全的单例
		
单例,大家肯定都不陌生,这是Java中很重要的一个设计模式.稍微了解一点单例的朋友也都知道实现单例是要考虑并发问题的,一般情况下,我们都会使用synchronized来保证线程安全. 那么,如果有这样 ...
 - 瞎扯设计模式1:单例模式 饿汉模式 懒汉模式 线程安全的单例 singleton 设计模式 java
		
[原创声明]此文为本人原创,欢迎转载,转载请注明出处,作者链接~ http://www.cnblogs.com/m-yb/p/8833085.html 单例很常用,面试也经常被问,如:不用自定义锁怎么 ...
 - 漫谈设计模式(二):单例(Singleton)模式
		
1.前言 实际业务中,大多业务类只需要一个对象就能完成所有工作,另外再创建其他对象就显得浪费内存空间了,例如web开发中的servlet,这时便要用到单例模式,就如其名一样,此模式使某个类只能生成唯一 ...
 - 【Java学习笔记之三十】详解Java单例(Singleton)模式
		
概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...
 - Android与设计模式——单例(Singleton)模式
		
概念: java中单例模式是一种常见的设计模式.单例模式分三种:懒汉式单例.饿汉式单例.登记式单例三种. 单例模式有一下特点: 1.单例类仅仅能有一个实例. 2.单例类必须自己自己创建自己的唯一实例. ...
 - JAVA中实现单例(Singleton)模式的八种方式
		
单例模式 单例模式,是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例.即一个类只有一个对象实例. 基本的实现思路 单 ...
 - 设计模式C++描述----01.单例(Singleton)模式
		
一.概念 单例模式:其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享. class CSingleton { //公有的静态方法,来获取该实例 public: s ...
 - 单例Singleton模式的两种实现方法
		
在设计模式中,有一种叫Singleton模式的,用它可以实现一次只运行一个实例.就是说在程序运行期间,某个类只能有一个实例在运行.这种模式用途比较广泛,会经常用到,下面是Singleton模式的两种实 ...
 - 一个单例(Singleton),并说明单例的目的和好处
		
单例的目的:保证一个类只有单一的实例,也就是说你无法通过new来创建这个类的一个新实例. 单例的好处:当一个对象在程序内部只能有一个实例的时候,它可以保证我们不会重复创建,而是始终指向同一个对象. S ...
 
随机推荐
- POJ2478 Farey Sequence
			
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 15023 Accepted: 5962 Description The ...
 - WML标签速查手册 wap标签
			
原文发布时间为:2010-08-19 -- 来源于本人的百度文章 [由搬家工具导入] WML标签速查手册(转)比较方便便于速查 结构相关标签 语法及属性 <wml> <wml x ...
 - css create 多边形 polygon
			
案例: 代码: element.style { width: 0; height: 0; /* border-left: 50px solid transparent; */ border-rig ...
 - SqlServer不允许更改字段类型(表中已有数据)
			
工具-选项-设计器-阻止保存要求重新创建表的更改,√去掉.
 - 了解 Oracle Berkeley DB 可以为您的应用程序带来 NoSQL 优势的原因及方式。
			
将 Oracle Berkeley DB 用作 NoSQL 数据存储 作者:Shashank Tiwari 2011 年 2 月发布 “NoSQL”是在开发人员.架构师甚至技术经理中新流行的一个词汇. ...
 - python - break和continue
			
break 终止整个循环:当循环或判断执行到break语句时,即使判断条件为True或者序列尚未完全被历遍,都会跳出循环或判断 for i in xrange(10): print(i) if i = ...
 - 安装glibc错误链接导致系统崩溃,u盘启动紧急救援模式下修复系统。
			
Sln 命令 创建动态符号链接 用法 sln source dest 故障案例:一个误操作 导致了一个不小的故障,输入所有命令都无效,直接系统无法启动. 故障描述 sln /usr/lib64/l ...
 - LeetCode OJ-- Integer to Roman @
			
@表示有更优解法 https://oj.leetcode.com/problems/integer-to-roman/ 将自然数,转换成罗马数字,输入范围为 1 ~ 3999,因为罗马数没有0. 用一 ...
 - 项目中使用libsodium扩展
			
前段时间研究了微信小微商户,地址:https://pay.weixin.qq.com/wiki/doc/api/xiaowei.php?chapter=19_11 其接口操作中需要下载证书针对返回的密 ...
 - iOS直播Liveroom组件,游客,用户多次切换登录同一直播间,消息出现多次重复问题解决
			
byzqk 新版,加入连麦功能,直播的流程修改很多,每次登录都需要登录liveroom组件 期间遇到一个奇葩的问题,就是游客登录组件之后,切换为用户登录,出现im消息重复的问题,一开始以为是游客退出不 ...