懒汉式实现的单例模式
上文中给出的懒汉式实现的单例模式,在单线程中使用时完全没有问题的,但是在多线程中使用会存在多次对象多次创建的问题。

  1. 线程A进入getInstance方法,并进入到if判断,因为现在m_psl是空指针,这时刚好线程A时间片用完,开始切换到线程B,线程B也调用getInstance方法创建了一个对象
  2. 线程B时间片用完,切换到线程A,这时线程A从if判断成功之后的下不开始,又创建了一遍对象,这时已经两次创建对象了

为了解决这个问题需要使用双检测,详情可参考
C++ and the Perils of Double-Checked Locking
里面详细说明了双重检测的方法,和最终的解决方案。

要想解决上述懒汉单例模式中的问题,需要引入这个双重检测的功能,实现也只需将图中的代码在加锁的基础上,在添加一层检测

临界区(Critical Section)。临界区对象通过提供一个进程内所有线程必须
共享的对象来控制线程。只有拥有那个对象的线程可以访问保护资源。在另一个线
程可以访问该资源之前,前一个线程必须释放临界区对象,以便新的线程可以索取对象的访问权

最终实现效果如下

if (m_psl == NULL)
{// 这里线程开始资源竞争,只有一个线程能获取lock的资源lock();if (m_psl == NULL){m_psl = new Singelton;}unlock();
}

说明:
lock里面判断一次,因为可能有多个线程在lock处等待,一个成功之后,会将m_psl设置为非空,这样下个线程就算拿到lock资源,再进去发现指针非空就离开了
lock外判断一次,是因为获取锁,是很浪费时间的,获取锁之外还有一层判断,那么在第二次获取单例对象的时候,lock外的if判断发现指针已经非空,就不会再获取锁了,直接返回了对应的对象,这样双层检测,即保证了对象创建的唯一性,又减少了获取锁浪费的时间和资源

不安全的单例模式代码:

#include <iostream>
using namespace std;//懒汉式
class Singelton
{private:Singelton(){cout << "Singelton 构造函数执行" << endl;}
public:static Singelton *getInstance(){if (m_psl == NULL){m_psl = new Singelton;}return m_psl;}static void FreeInstance(){if (m_psl != NULL){delete m_psl;m_psl = NULL; }}private:static Singelton *m_psl;
};Singelton *Singelton::m_psl = NULL;void main041()
{Singelton *p1 = Singelton::getInstance();Singelton *p2 = Singelton::getInstance();if (p1 == p2){cout << "是同一个对象" << endl;}else{cout << "不是同一个对象" << endl;}Singelton::FreeInstance();return ;
}

c++中的 单例模式(singleton)和双检测锁(Double-Checked Locking)相关推荐

  1. 单例模式,懒汉饿汉,线程安全,double checked locking的问题

    概览 本文目的 单例 饿汉模式 懒汉模式 线程安全的Singleton实现 懒汉普通加锁 double checked locking double checked locking 靠不住? 静态局部 ...

  2. java 双重检查锁 有序_Java中的双重检查锁(double checked locking)

    1 public classSingleton {2 private staticSingleton uniqueSingleton;3 4 privateSingleton() {5 }6 7 pu ...

  3. 单例模式(懒汉模式-双检锁、饿汉模式、静态内部类模式)-详细

    文章目录 前言 单例模式(懒汉模式-双检锁.饿汉模式.静态内部类模式)-详细 01 单例模式是什么? 02 单例模式的好处? 03 单例模式的三种模式 03::01 懒汉模式 03::01::01 问 ...

  4. Java中的双重检查锁(double checked locking)

    起因 在实现单例模式时,如果未考虑多线程的情况,很容易写出下面的代码(也不能说是错误的): public class Singleton {private static Singleton uniqu ...

  5. python3中的单例模式Singleton

    #!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2019-01-21 09:09:09 # @Author : cdl (1217096 ...

  6. 【C++】C/C++ 中的单例模式

    目录 part 0:单例模式3种经典的实现方式 Meyer's Singleton Meyers Singleton版本二 Lazy Singleton Eager Singleton Testing ...

  7. 在Java中实现单例模式的有效方法是什么? [关闭]

    在Java中实现单例模式的有效方法是什么? #1楼 我使用Spring框架来管理我的单身人士. 它不会强制类的"单一性"(如果涉及多个类加载器,您将无法真正做到),但是它提供了一种 ...

  8. 2021面试 Lock,synch,dcl双检查锁sy+volite,悲观锁,偏向,轻量锁,重量锁,升级12

    0.数据库悲观锁:for update: MySQL实现悲观锁_九色鹿-CSDN博客_mysql悲观锁怎么实现 1. ReentrantLock锁公平与非公平实现.重入原理:  ReentrantLo ...

  9. 【设计模式】单例模式 Singleton Pattern

    通常我们在写程序的时候会碰到一个类只允许在整个系统中只存在一个实例(Instance)  的情况, 比如说我们想做一计数器,统计某些接口调用的次数,通常我们的数据库连接也是只期望有一个实例.Windo ...

最新文章

  1. Struts2自定义Result处理JSON
  2. wordpress多站点主站调用分站最新文章_企业网站SEO最新的7个优化步骤!
  3. oracle-11g-R2监听文件配置
  4. SQL Server 加密层级
  5. C语言丨检测用户键盘输入数据的合法性
  6. 高可用,完全分布式Hadoop集群HDFS和MapReduce安装配置指南
  7. mysql中不重复_mysql中distinct的用法(不重复记录)
  8. php 实用 函数,PHP实用函数9
  9. comsol频域模拟
  10. 信工所复试收集材料分享
  11. 2021iGEM感想
  12. Java递归求全排列详解
  13. 如何在输入特殊符号,例如角度“∠”
  14. VxWorks下 canOpen移植心得 stm32 - ppc
  15. ubuntu18.04安装截图软件shutter
  16. ADDS:检查 AD Domain 的健康和复制状态
  17. 基于javaweb的出租车管理系统(java+ssm+html+javascript+jsp+mysql)
  18. 最新模版兔-基于laysns系统开发2.55可用
  19. [模拟拖拽] 模拟将一个文件拖拽到一个软件窗口上,实现拖拽操作(微信语音播放器)...
  20. 【人事】电话面试时需要注意什么

热门文章

  1. 玩转VIM编辑器-vim附加特性
  2. 《快速软件开发——有效控制与完成进度计划》
  3. Enterprise Library 5.0
  4. NYOJ 158 省赛来了
  5. hdu 4556 Stern-Brocot Tree
  6. NYOJ 201 作业题 动态规划
  7. Jquery----实现抽奖效果(根据姓名抽奖)
  8. Docker 入门(Mac环境)- part 5 stacks
  9. 【codeforces 765F】 Souvenirs
  10. HttpContext.Cache属性