Double Checked Locking模式:
class Singleton
{
public:
static Singleton *instance (void)
{
if (instance_ == 0)
{
Guard lock (lock_)
if (instance_ == 0)
{
instance_ = new Singleton;
}
}
return instance_;
}
private:
static Singleton *instance_;
};
上面所说的Double Checked Locking模式有下面优点:
1、最小化加锁。通过实现两个flag检测(第一个flag采用模糊匹配,第二个flag采用精确定位),Double Checked Locking模式实现通常用例的优化。
但是同时此模式存在也会带来致命的缺陷:
1、如果使用Double Checked Locking模式的软件被移植到没有原子性的指针和正数赋值语义的硬件平台上。例如,如果一个instance_指针被用来作为Singleton实现的flag,instance_指针中的所有位(bit)必须在一次操作中完成读和写。如果将new的结果写入内存不是一个原子操作,其他的线程可能会试图读取一个不健全的指针,这将导致非法的内存访问。在一些允许内存地址跨越对齐边界的系统上这种现象是可能的,因此每次访问需要从内存中取两次。在这种情况下,系统可能使用分离的字对齐合成flag,来表示 instance_指针。
2、某些编译器可能在优化过程中采用某种缓冲手段来优化flag,或是移除了第二个flag==0检测。
针对这两个缺陷,现在我们提出了一种解决方案:
Double Checked Locking 模式:
01class Singleton
02{
03public:
04static Singleton *instance (void)
05{
06// 第一个模糊检测
07if (instance_ == 0)
08{
09 //模糊区域
10Guard guard (lock_);
11// 第二次检测
12if (instance_ == 0) //精确定位
13instance_ = new Singleton;
14}
15return instance_;
16// 释放锁.
17}
18private:
19static Mutex lock_;
20static Singleton *instance_;
21};
改进版本的Double Checked Locking 模式:
01class Singleton
02{
03public:
04static Singleton *instance (void)
05{
06// 第一个模糊检测
07if (instance_test_ == 0)//