关于DCLP实现的单例模式的一些想法

我之前写过单例的文章( http://www.cnblogs.com/mkdym/p/4908644.html ),但是现在又有了一些想法,不想再在原来那篇文章上更新,所以独开一篇。

看到一些书或者文章讲单例模式的时候,总要说起DCLP,并且得出的结论是DCLP是不可靠的,也就不能用它来实现单例。即下面这样做是错误的:

class SingletonAA
{
public:
static SingletonAA& get_instance_ref()
{
if (NULL == p_) // 1st check
{
scoped_lock lock;
if (NULL == p_) // 2nd check
{
p_ = new SingletonAA();
}
}
return *p_;
} private:
SingletonAA()
{
//...
} ~SingletonAA()
{
//...
} private:
static SingletonAA *p_; }; SingletonAA *SingletonAA::p_ = NULL;

因为new那一句不是原子的,分了3步,而且顺序不一定,这个顺序又会影响第一次检查的结果。接着他们又讨论了volatile关键字和乱序优化,然后得出结论这个关键字也不能使DCLP变得正确,或者说不能轻松的使DCLP变得正确。

但是他们讲这个问题的时候全部的前提是用单例对象的指针本身去做了判断条件,这就是诱因:单例对象的创建和单例的判断是对同一个元素读写,而“写”太“复杂”了!

那么我不用单例对象去做判断不就行了吗?如下:

class SingletonAA
{
public:
static SingletonAA& get_instance_ref()
{
if (!init_flag_) // 1st check
{
scoped_lock lock;
if (!init_flag_) // 2nd check
{
p_ = new SingletonAA();
init_flag_ = true;
}
}
return *p_;
} private:
//... private:
static SingletonAA *p_;
static bool volatile init_flag_;
}; SingletonAA *SingletonAA::p_ = NULL;
bool volatile SingletonAA::init_flag_ = false;

我换用一个bool标志,bool变量在vc上是一个字节的,操作只需一条指令,是原子的。而且声明成volatile,确保编译器不对它做优化。

按我的不准确的知识,编译器或CPU可能会对

p_ = new SingletonAA();

init_flag_ = true;

这两句调整顺序,因为他们两句没有关联,这就又会出错。那么我制造一个关联:

init_flag_ = p_ ? true : false;

使init_flag_的赋值依赖于对象的创建,按我的理解,此时编译器和CPU都应该使设置标志语句后于对象创建语句,那么就没有错误了。

假如编译器认为p_在执行完new后一定不为0,那么它就又可以优化init_flag_的赋值了。那么这种情况会不会出现,编译器是否会这样认为?

Need Help

Need Help

Need Help

(重说三)

因为我想得到大家的关注,所以可耻的勾选了“发布至博客园首页”,如果最后没有在首页出现,我就把这句话删掉,免的丢我的小脸。

关于DCLP实现的单例模式的一些想法的更多相关文章

  1. Java设计模式4:单例模式

    前言 非常重要,单例模式是各个Java项目中必不可少的一种设计模式.本文的关注点将重点放在单例模式的写法以及每种写法的线程安全性上.所谓"线程安全性"的意思就是保证在创建单例对象的 ...

  2. 【Java】Java 深入探讨 单例模式的实现

    在GoF的23种设计模式中,单例模式是比较简单的一种.然而,有时候越是简单的东西越容易出现问题.下面就单例设计模式详细的探讨一下.   所谓单例模式,简单来说,就是在整个应用中保证只有一个类的实例存在 ...

  3. 深入Java单例模式【转载】

    在GoF的23种设计模式中,单例模式是比较简单的一种.然而,有时候越是简单的东西越容易出现问题.下面就单例设计模式详细的探讨一下.   所谓单例模式,简单来说,就是在整个应用中保证只有一个类的实例存在 ...

  4. 单例模式(Winform窗体的实现)

    在我的设计模式分类当中,我选择单例模式作为我第一个要写的设计模式,其一,单例模式简单.容易理解让人接受,其二,单例模式很常用,在实际的Winform窗体应用开发中能够带来更好的客户体验. 单例模式的核 ...

  5. java中的单例模式与doublecheck

    转自: http://devbean.blog.51cto.com/448512/203501 在GoF的23种设计模式中,单例模式是比较简单的一种.然而,有时候越是简单的东西越容易出现问题.下面就单 ...

  6. 【转载】深入Java单例模式

    原文出处:http://devbean.blog.51cto.com/448512/203501 在GoF的23种设计模式中,单例模式是比较简单的一种.然而,有时候越是简单的东西越容易出现问题.下面就 ...

  7. java模式:深入单例模式

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://devbean.blog.51cto.com/448512/203501 在GoF ...

  8. 深入Java单例模式

    在GoF的23种设计模式中,单例模式是比较简单的一种.然而,有时候越是简单的东西越容易出现问题.下面就单例设计模式详细的探讨一下.  所谓单例模式,简单来说,就是在整个应用中保证只有一个类的实例存在. ...

  9. 深入Java单例模式(转)

    深入Java单例模式 源自 http://devbean.blog.51cto.com/448512/203501 在GoF的23种设计模式中,单例模式是比较简单的一种.然而,有时候越是简单的东西越容 ...

随机推荐

  1. WARNING: The following packages cannot be authenticated! foo bar baz Install these packages without verification [y/N]?

    apt-get install debian-archive-keyring apt-get update

  2. PHP MAIL DEMO(程序代码直接发送邮件)

    php代码 <?php // 收件人邮箱地址 $to = 'xxxxxx@qq.com'; // 邮件主题 $title = '测试邮件发送'; // 邮件内容 $msg = '这是一封测试邮件 ...

  3. MfC基础--绘图基础--win32

    1.vc使用的控件分为三类: windows标准控件--MFC对这些进行了再封装 ActiveX 控件 其他MFC控件类 2.CWind是所有窗口的基类 3.GDI也属于一种API,主要用于绘图,(G ...

  4. js实现点击ul/li等改变背景颜色

    今天项目遇到了标题所说的问题,找到一篇很高效的例子,值得学习. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//E ...

  5. 操作html标签之找到标签(续)

    为了方便我们快速地找到一些特殊的元素,js提供了几个有用的东东. 1.快速找到根元素:document.documentElement和document.body. 2.obj.parentNode: ...

  6. sqlserver2008 case when then else end

    在写sql语句的时候,有时候我们需要对字段的只进行判断计算.查看了下相关文档在sql2012.sql2014里边可以使用  IIF 函数直接完成. 但是现在我需要在sql2008版本中完成最字段的计算 ...

  7. 原 iOS面试题收集

    原 iOS面试题收集 发表于2年前(2013-07-22 13:47)   阅读(369) | 评论(0) 4人收藏此文章, 我要收藏 赞0 听云性能监测产品App.Server.CDN免费试用,绑定 ...

  8. VirtualBox虚拟机无法选择桥接方式

    VirtualBox 装好之后默认的网络是NAT模式,但这种模式中虚拟机配置的IP和主机的不再同一网段内,无法获得和主机一样的局域网地位,更不可能从主机用远程桌面携带硬盘的方式远程控制.而最简便的方法 ...

  9. Redhat Enterprise Linux中如何关闭SELinux?

    转自http://www.cnitblog.com/lywaml/archive/2005/06/21/468.html 红帽企业 Linux 4 包括了一个 SELinux 的实现.SELinux ...

  10. NLog 2.0.0.2000 使用实例

    原文地址:http://www.cnblogs.com/sorex/archive/2013/01/31/2887174.html ---------------------------------- ...