#pragma once
#pragma once
//原文参考:
//1.https://www.cnblogs.com/ccdev/archive/2012/12/19/2825355.html
//2.https://blog.youkuaiyun.com/crayondeng/article/details/24853471
//懒汉模式:即第一次调用该类实例的时候才产生一个新的该类实例,并在以后仅返回此实例
//需要用锁,来保证其线程安全性
//原因:多个线程可能进入判断是否已经存在实例的if语句,从而nonthread safety
//使用double-check来保证thread safety,但是如果处理大量数据时,该锁会成为严重的性能瓶颈
//1.静态成员实例的懒汉模式
#include <mutex>
namespace wzl1
{
class Singleton
{
private:
static Singleton* m_instance;
static std::mutex m;
Singleton() {}
public:
static Singleton* getInstance();
static void Destroy();
};
std::mutex Singleton::m;
Singleton* Singleton::m_instance = nullptr;
Singleton* Singleton::getInstance()
{
if (nullptr == m_instance)
{
std::lock_guard<std::mutex> lck(m);
if (nullptr == m_instance)//double-check,防止两个线程同时构造一个实例
{
m_instance = new Singleton;
}
}
return m_instance;
}
void Singleton::Destroy()
{
if (m_instance)
{
delete m_instance;
m_instance = nullptr;
}
}
}
//内部静态实例的懒汉模式
//C++11以后,要求编译器保证内部静态变量的线程安全性,可以不加锁,之前需要加
namespace wzl2
{
class Singleton
{
private:
Singleton() {}
public:
static Singleton& getinstance();
};
Singleton& Singleton::getinstance()
{
std::lock_guard<std::mutex> lck(m);
static Singleton instance;
return instance;
}
}
//饿汉模式:即无论是否调用该类的实例,在程序开始时就会产生一个该类的实例,并在以后仅返回此实例
//由静态初始化实例保证其线程安全性,WHY?因为静态实例初始化在程序开始进入主函数之前就由主线程以单线程方式完成了初始化,不必担心多线程问题
//故在性能需求较高时,应使用这种模式,避免频繁的锁争夺
namespace wzl3
{
class Singleton
{
private:
/*
const:保证这个单例对象不会被修改
static:保证这个单例对象在程序开始时进入主函数之前就被初始化了,而且是线程安全的
*/
static const Singleton* m_instance;
Singleton() {}
public:
static const Singleton* getInstance()
{
return m_instance;
}
static void Destroy();
};
//外部初始化 before invoke main
const Singleton* Singleton::m_instance = new Singleton;
void Singleton::Destroy()
{
if (m_instance)
{
delete m_instance;
m_instance = nullptr;
}
}
}
//boost库中的单例模式实现
namespace wzl4 {
template<typename T>
class Singleton
{
struct object_creator
{
object_creator()
{
Singleton<T>::instance();
}
inline void do_something() const {}
};
static object_creator create_object;
public:
typedef T object_type;
static T& instance()
{
static T obj;
//这个do_something是确保create_object构造函数被调用
//这跟模板的编译有关
create_object.do_something();
return obj;
}
};
template<typename T>
typename Singleton<T>::object_creator Singleton<T>::create_object;
}