C++的双重检查锁并不安全(转)
一个典型的单例模式构建对象的双重检查锁如下:
static Singleton * getSingleObject()
{
if(singleObject==NULL)
{
lock();
if(singleObject==NULL)
{
singleObject = new Singleton();
}
unlock();
}
return singleObject;
}
该代码的逻辑是:getSingleObject()函数获得对象,如果对象不存在则创建,反之则直接返回。考虑到线程安全,创建对象时需要加锁(否则可能多线程同时调用该函数时创建多个对象)。同时为了避免线程每次调用getSingleObject()函数时候都要被锁住等待,减小线程间的开销,使用双重检查锁,即只有对象不存在时才锁住等待。
看起来天衣无缝……
C++在new一个对象时,首先会把指针指向分配的那块空间,然后在初始化该空间。
这样假设线程A执行到new该对象时,分配了指针,但是还未来得及构建那块空间。此时线程B执行getSingleObject()函数,由于指针已经分配所以直接返回该地址(但其实是一块还未初始化的地址),线程B操作该地址,game over。。
一种解决方法,但还是有可能出错:
class Singleton {
public:
static volatile Singleton* volatile instance();
...
private:
// one more volatile added 加入另一个volatile声明
static volatile Singleton* volatile pInstance;
};
// from the implementation file 实现文件内容如下
volatile Singleton* volatile Singleton::pInstance = ;
volatile Singleton* volatile Singleton::instance() {
if (pInstance == ) {
Lock lock;
if (pInstance == ) {
// one more volatile added 加入另一个volatile声明
volatile Singleton* volatile temp =
new volatile Singleton;
pInstance = temp;
}
}
return pInstance;
}
C++的双重检查锁并不安全(转)的更多相关文章
- 单例模式中用volatile和synchronized来满足双重检查锁机制
背景:我们在实现单例模式的时候往往会忽略掉多线程的情况,就是写的代码在单线程的情况下是没问题的,但是一碰到多个线程的时候,由于代码没写好,就会引发很多问题,而且这些问题都是很隐蔽和很难排查的. 例子1 ...
- Java中的双重检查锁(double checked locking)
最初的代码 在最近的项目中,写出了这样的一段代码 private static SomeClass instance; public SomeClass getInstance() { if (nul ...
- 双重检查锁实现单例(java)
单例类在Java开发者中非常常用,但是它给初级开发者们造成了很多挑战.他们所面对的其中一个关键挑战是,怎样确保单例类的行为是单例?也就是说,无论任何原因,如何防止单例类有多个实例.在整个应用生命周期中 ...
- Java基础教程:多线程杂谈——双重检查锁与Volatile
Java基础教程:多线程杂谈——双重检查锁与Volatile 双重检查锁 有时候可能需要推迟一些高开销的对象初始化操作,并且只有在使用这些对象时才进行初始化.此时程序员可能会采用延迟初始化.但要正确实 ...
- 【Java学习笔记】线程安全的单例模式及双重检查锁—个人理解
搬以前写的博客[2014-12-30 16:04] 在web应用中服务器面临的是大量的访问请求,免不了多线程程序,但是有时候,我们希望在多线程应用中的某一个类只能新建一个对象的时候,就会遇到问题. 首 ...
- 对象部分初始化:原理以及验证代码(双重检查锁与volatile相关)
对象部分初始化:原理以及验证代码(双重检查锁与volatile相关) 对象部分初始化被称为 Partially initialized objects / Partially constructed ...
- 为什么双重检查锁模式需要 volatile ?
双重检查锁定(Double check locked)模式经常会出现在一些框架源码中,目的是为了延迟初始化变量.这个模式还可以用来创建单例.下面来看一个 Spring 中双重检查锁定的例子. 这个例子 ...
- 双重检查锁单例模式为什么要用volatile关键字?
前言 从Java内存模型出发,结合并发编程中的原子性.可见性.有序性三个角度分析volatile所起的作用,并从汇编角度大致说了volatile的原理,说明了该关键字的应用场景:在这补充一点,分析下v ...
- 从学习“单例模式”学到的Java知识:双重检查锁和延迟初始化
一切真是有缘,上午刚刚看完单例模式,还在为其中的代码块同步而兴奋,下午就遇见这篇文章:双重检查锁定与延迟初始化.我一看,文章开头语出惊人,说这是一种错误的优化,我说,难道上午学的东西下午就过时了吗?仔 ...
随机推荐
- JavaWeb开发小结
JavaWeb开发是B/S开发的一种,其他语言也可以实现,就前台而言,一直都是HTML.CSS.JavaScript 后台语言可以是Perl.Python.PHP.Java等等 Java机缘巧合在We ...
- proteus仿真 引脚显示电平变化但不能显示波形
proteus仿真 引脚显示电平变化但不能显示波形 原来是没有选择通道问题,proteus默认优先使用A通道才会显示波形,如果优先使用B,C,D通道,需要选择...
- Java实现简单的socket通信
今天学习了一下java如何实现socket通信,感觉难点反而是在io上,因为java对socket封装已经很完善了. 今天代码花了整个晚上调试,主要原因是io的flush问题和命令行下如何运行具有pa ...
- hihoCoder 1133 二分·二分查找之k小数(TOP K算法)
#1133 : 二分·二分查找之k小数 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回里我们知道Nettle在玩<艦これ>,Nettle的镇守府有很 ...
- 【CCF】路径解析 模拟
#include<iostream> #include<cstdio> #include<string> #include<cstring> #incl ...
- python(6)-- 模块
python模块: 定义:Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句. 作用:(a) 模块让你能够有逻辑地组织你 ...
- [01] radio ,checkbox 表单文字对齐
http://www.cnblogs.com/wangsir015/p/5555818.html 这几天在做表单时总会碰到复选框(checkbox)和单选框(radio)与文字不对齐的问题,要不是ch ...
- mongoDB权威指南学习笔记
//mongoDB第1-3章节添加,修改,修改器的笔记: //备注:和MySQL查询一样,时刻想着优化查询数据的时间和性能 //db.help() //数据库帮助信息 //db.blog.help() ...
- .bat 处理错误码
某些命令只会返回error level,而要添加互操作性,.bat文件的返回值,exit code应该最后指定,那么需要,在这个单行的命令后面单个添加处理error level 的语句,最后再做统一的 ...
- vim配置文件解析
我的vim配置文件如下: "根据时段的不同自动选择不同的配色方案 ""if strftime("%H") < 6 "6:00 ...