在设计单例模式的时候。尽管非常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)模式的更多相关文章

  1. 不使用synchronized和lock,如何实现一个线程安全的单例

    单例,大家肯定都不陌生,这是Java中很重要的一个设计模式.稍微了解一点单例的朋友也都知道实现单例是要考虑并发问题的,一般情况下,我们都会使用synchronized来保证线程安全. 那么,如果有这样 ...

  2. 瞎扯设计模式1:单例模式 饿汉模式 懒汉模式 线程安全的单例 singleton 设计模式 java

    [原创声明]此文为本人原创,欢迎转载,转载请注明出处,作者链接~ http://www.cnblogs.com/m-yb/p/8833085.html 单例很常用,面试也经常被问,如:不用自定义锁怎么 ...

  3. 漫谈设计模式(二):单例(Singleton)模式

    1.前言 实际业务中,大多业务类只需要一个对象就能完成所有工作,另外再创建其他对象就显得浪费内存空间了,例如web开发中的servlet,这时便要用到单例模式,就如其名一样,此模式使某个类只能生成唯一 ...

  4. 【Java学习笔记之三十】详解Java单例(Singleton)模式

    概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...

  5. Android与设计模式——单例(Singleton)模式

    概念: java中单例模式是一种常见的设计模式.单例模式分三种:懒汉式单例.饿汉式单例.登记式单例三种. 单例模式有一下特点: 1.单例类仅仅能有一个实例. 2.单例类必须自己自己创建自己的唯一实例. ...

  6. JAVA中实现单例(Singleton)模式的八种方式

    单例模式 单例模式,是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例.即一个类只有一个对象实例. 基本的实现思路 单 ...

  7. 设计模式C++描述----01.单例(Singleton)模式

    一.概念 单例模式:其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享. class CSingleton { //公有的静态方法,来获取该实例 public: s ...

  8. 单例Singleton模式的两种实现方法

    在设计模式中,有一种叫Singleton模式的,用它可以实现一次只运行一个实例.就是说在程序运行期间,某个类只能有一个实例在运行.这种模式用途比较广泛,会经常用到,下面是Singleton模式的两种实 ...

  9. 一个单例(Singleton),并说明单例的目的和好处

    单例的目的:保证一个类只有单一的实例,也就是说你无法通过new来创建这个类的一个新实例. 单例的好处:当一个对象在程序内部只能有一个实例的时候,它可以保证我们不会重复创建,而是始终指向同一个对象. S ...

随机推荐

  1. 关于 react state的改变数据上面的一点问题

    在react当中 比如说 this.state = { loginInfo: { account: "...", password: "..." } } thi ...

  2. [区别]APPlication,Session,Cookie,ViewState和Cache

    原文发布时间为:2009-08-01 -- 来源于本人的百度文章 [由搬家工具导入] 在ASP.NET中,有很多种保存信息的对象.例如:APPlication,Session,Cookie,ViewS ...

  3. Android开发基础(java)14

    Java语言与其他编程语言的最大不同之处在于:java有专门的异常处理机制,实现对各类异常情况进行有效控制. 一.基本概念:异常和错误的区别与联系: (1).定义形式不同:异常为exception:错 ...

  4. python 集合比较(交集、并集,差集)

    python的set和其他语言类似, 是一个无序不重复元素集, 基本功能包括关系测试和消除重复元素. 集合对象还支持union(联合), intersection(交), difference(差)和 ...

  5. Markdown语法格式

    Markdown是一种可以普通文本编辑器编写的标记语言,通过简单的标记语法,就可以使普通文本内容具有一定的格式.(摘自百度百科) 今天记录一下Markdown语法,以供以后使用时查询. 1.标题 用 ...

  6. C#生成高清缩略图的方法

    /// <summary> /// 为图片生成缩略图 /// </summary> /// <param name="phyPath">原图片的 ...

  7. 牛客网 牛客练习赛13 A.幸运数字Ⅰ

    A.幸运数字Ⅰ 链接:https://www.nowcoder.com/acm/contest/70/A来源:牛客网     水题.   代码: #include<iostream> #i ...

  8. 51Nod 1019 逆序数(线段树)

    题目链接:逆序数 模板题. #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a) ...

  9. redis入门与集群部署

    redis入门 redis入门级教程非常多,如http://www.runoob.com/redis/redis-backup.html,作为入门其实已经十分详细了,主要学习内容有如下几个方面吧 1. ...

  10. Unity工程资源破解

        Unity工程资源提取其实还是很方便的,网上也有很多相关介绍,比如雨凇就专门写了一遍关于破解Unity资源的文章(http://www.xuanyusong.com/archives/3618 ...