当前位置: 首页 > news >正文

Singleton Pattern 单例模式

       单例模式,顾名思义是确保一个类只有一个实例,并提供一个全局访问点。有一些对象我们只需要一个。例如对话框、线程池、注册表对象、日志对象等。事实上,这类对象只能有一个实例,如果制造出多个实例,就会导致出现问题。

       为了只有一个实例。有很多方法,例如声明全局变量。但是单件模式是更好的做法,是久经时间考验的方法。全局模式有固有的缺点。例如如果将一个对象赋值给一个全局变量,那么你必须在程序一开始就创建好对象,万一这个对象非常耗费资源,而程序在这次执行过程中又一直没有用到它,不就形成了浪费了吗?而单例模式,我们可以在需要时才创建对象。


经典的单例模式实现:


class Singleton{
private:
    Singleton(){
        //构造函数是私有的,只有类内才能访问构造函数
    }
    static Singleton* uniqueInstance;  //用一个静态变量来记录Singleton类的唯一实例
public:
    static Singleton* getInstance()
    {
     if(uniqueInstance==NULL){
        uniqueInstance=new Singleton();
     }
     return uniqueInstance;
    }

};
   用户获取实例的方法只能调用getInstance方法,其他任何尝试都会失败,因为构造方法是私有的。


   对于多线程调用,以上代码是不安全的,依然有可能会出现生成多个实例。主要原因是因为在getInstance()方法并非同步的或者加锁的,不具有原子性,可能被多线程穿插调用。那么考虑到线程安全可以做一下改进:

//考虑到线程安全
class Lock{
private:
    CCriticalSection m_cs; //临界区
public:
    Lock(CCriticalSection cs):m_cs(cs)
    {
        m_cs.Lock();    
    }
    ~Lock(){
        m_cs.Unlock();
    }
};


class Singleton_safe{
private:
    Singleton_safe(){}
    static Singleton_safe *UniqueSingleton;
    static CCriticalSection cs;
public:
    static Singleton_safe* getInstance(){
        if(UniqueSingleton==NULL){
            Lock(cs);
            if(UniqueSingleton==NULL){
                UniqueSingleton=new Singleton_safe();
            }
        }
    }
};

      其中,判断UniqueSingleton是否为空用了两次,主要是因为大多数(除1次以外)UniqueSingleton不为NULL。所以,加锁只有一次会调用,避免了每次判断都加锁,大大的降低了加锁开销。


学习:http://blog.csdn.net/hackbuteer1/article/details/7460019

相关文章:

  • 浏览器也能当操作系统!——3款中文浏览器操作系统体验评测
  • Linux进程管理中的hash
  • 浏览器真的能“永不假死”?——六款主流浏览器防假死功能测试
  • [九度—剑指offer]—二维数组查找
  • 人人都能当“苍天哥” 手把手教你制作游戏视频
  • Linux 2.6 中导出sys_call_table表修改系统调用函数
  • [九度 1510 剑指offer]—替换空格 数组插入逆向移动
  • 个人设置随身携带口袋操作系统手到擒来
  • 免费邮箱,谁更可靠?6款常用免费邮箱收信效果对比测试
  • 哪个搜索引擎更聪明?微软必应搜索挑战赛
  • [九度1512 剑指offer7] 用两个栈实现队列
  • 无光驱没光盘 操作系统照样可以安
  • mmap() 实现文件复制
  • [Linux内存管理-分页机制]—把一个虚拟地址转换为物理地址
  • C#也能动态生成Word文档并填充数据
  • angular2开源库收集
  • CSS相对定位
  • Java Agent 学习笔记
  • JDK 6和JDK 7中的substring()方法
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • Objective-C 中关联引用的概念
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • react 代码优化(一) ——事件处理
  • 百度小程序遇到的问题
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 开源地图数据可视化库——mapnik
  • 前端设计模式
  • 悄悄地说一个bug
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 使用common-codec进行md5加密
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 为什么要用IPython/Jupyter?
  • 小程序开发中的那些坑
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • ​3ds Max插件CG MAGIC图形板块为您提升线条效率!
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • #pragma multi_compile #pragma shader_feature
  • (11)MSP430F5529 定时器B
  • (6)设计一个TimeMap
  • (C语言)二分查找 超详细
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (HAL库版)freeRTOS移植STMF103
  • (Note)C++中的继承方式
  • (第8天)保姆级 PL/SQL Developer 安装与配置
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (三)c52学习之旅-点亮LED灯
  • (三)docker:Dockerfile构建容器运行jar包
  • (四)c52学习之旅-流水LED灯
  • (四)图像的%2线性拉伸
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • (转)shell调试方法
  • (转)大型网站的系统架构
  • (转载)利用webkit抓取动态网页和链接
  • .net framwork4.6操作MySQL报错Character set ‘utf8mb3‘ is not supported 解决方法