一、
class Singleton
{
public:
static Singleton* Get()
{
static Singleton s;
return &s;
}
private:
Singleton()
{
printf("hello");
}
};
上述实现方式的线程安全性依赖编译器。如果编译器实现了“静态局部对象初始化的线程安全”那么它是线程安全的,否则不是。visual studio 2015及以后实现了这个特性。关联文档如下:
关于“静态局部对象初始化的线程安全”的文档如下:(1)在visual studio 2015 的更新说明文档中,Thread-Safe "Magic" Statics Static local variables are now initialized in a thread-safe way, eliminating the need for manual synchronization. Only initialization is thread-safe, use of static local variables by multiple threads must still be manually synchronized. The thread-safe statics feature can be disabled by using the /Zc:threadSafeInit- flag to avoid taking a dependency on the CRT. (C++11)。(2)在“ISOIEC 14882 2011”的第6.7.4节的描述为“If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.”
我这里有个测试结果供参考,上述代码在visual studio 2012和visual studio 2015生成的汇编文件不同,如下图:
二、
class Singleton
{
public:
static Singleton* Get()
{
return &s;
}
private:
Singleton()
{
printf("hello");
}
private:
static Singleton s;
};
Singleton Singleton::s;
三、
class Singleton
{
public:
static Singleton* Get()
{
lock_guard<mutex> lock(mut_);
if (ins_ == nullptr)
{
ins_ = new Singleton();
}
return ins_;
}
static void Destroy()
{
lock_guard<mutex> lock(mut_);
if (ins_ != nullptr)
{
delete ins_;
ins_ = nullptr;
}
}
private:
Singleton()
{
printf("hello\n");
};
private:
static Singleton* ins_;
static mutex mut_;
};
Singleton* Singleton::ins_;
mutex Singleton::mut_;
四、
class Singleton
{
public:
static Singleton* Get()
{
if (ins_ == nullptr)
{
lock_guard<mutex> lock(mut_);
if (ins_ == nullptr)
{
ins_ = new Singleton();
}
}
return ins_;
}
static void Destroy()
{
lock_guard<mutex> lock(mut_);
if (ins_)
{
delete ins_;
ins_ = nullptr;
}
}
private:
Singleton()
{
printf("hello\n");
};
private:
volatile static atomic<Singleton*> ins_;
static mutex mut_;
};
volatile atomic<Singleton*> Singleton::ins_ = nullptr;
mutex Singleton::mut_;
五、
class Singleton
{
public:
static Singleton* Get()
{
std::call_once(oc_,[]() { ins_ = new Singleton(); });
return ins_;
}
private:
Singleton()
{
printf("hello\n");
};
private:
static Singleton* ins_;
static std::once_flag oc_;
};
Singleton* Singleton::ins_ = nullptr;
std::once_flag Singleton::oc_;
六、
class Singleton
{
public static Singleton Instance
{
get
{
return _lazy_ins.Value;
}
}
private Singleton()
{
Console.WriteLine("hello");
}
private static readonly Lazy<Singleton> _lazy_ins = new Lazy<Singleton>(() => { return new Singleton(); });
}