单例模式的线程安全的实现(五种C++的实现方式和一种C#的实现方式)

一、

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(); });
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值