浅析单例模式与线程安全(Linux环境c++版本)

什么是单例模式

单例模式是设计模式中一种常用模式,定义是Ensure a class has only one instance, and provide a global point of access to it.(确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例)

用《设计模式之禅》里的话说,就是,在一个系统中,要求一个类有且仅有一个对象,如果出现多个就会出现“不良反应”,比如以下情景可能会用到单例模式

  • 要求生成唯一序列号的环境
  • 在整个项目中需要一个共享访问点或者共享数据,例如一个Web页面上的计数器,可以不用把每次的刷新纪录都记录到数据库中,使用单例模式保持计数器的值(要涉及到稍后谈到的线程安全)
  • 创建一个对象需要都消耗资源过多,比如访问IO和数据库资源
  • 需要定义大量的静态常量和静态方法(如工具类)


单例模式的优点

  • 由于单例模式在内存中只有一个实例,减少了内存开支,特别是一个对象需要频繁地创建、销毁时,而且创建或销毁时性能又无法优化,单例模式的作用很明显
  • 减少了系统的性能开支,当一个对象的产生需要比较多的资源时,如读取数据,产生其他依赖对象时,可以通过在应用启动时直接产生一个单例对象,永驻内存
  • 避免对资源的多重占用,例如写一个文件动作,由于只有一个实例存在内存中,避免了对同一个资源的同时写操作
  • 可以在系统设置全局的访问点,优化共享资源,例如可以设计一个单例类,负责所有数据表的映射处理


单例模式实现

单线程实现

说了这么多,但是模式如何设计?

为了避免后面的派生类继承这个类,误将该类多次初始化(即内存中多个备份),我们应该将其构造函数设为私有,并且把唯一的一次初始化留到静态函数中,比如c++写出来是这样的

#include <iostream>

template<typename T>
class Singleton
{
public:
	static T& instance()
	{
		if (flag_init)
		{
			flag_init = false;
			flag_destory = true;
			init();
		}
		return *value_;
	}

	static void init()
	{
		value_ = new T();
	}

	static void destory()
	{
		if (flag_destory)
		{
			flag_destory = false;
			suicide();
		}
	}

	static void suicide()
	{
		delete value_;
	}

private:
  	static T* value_;       //只进行一次的初始化的指针
	static bool flag_init;     //表明是否可以进行初始化的标志位
	static bool flag_destory; //表明是否进行过销毁的标志位

	Singleton(){}            //私有函数,导致无法多次初始化这个类
	~Singleton(){}           //私有函数,导致无法多次销毁这个类
};

//静态变量必须在外面初始化
template<typename T>
T* Singleton<T>::value_ = NULL;

template<typename T>
bool Singleton<T>::flag_destory = false;

template<typename T>
bool Singleton<T>::flag_init = true;

//测试单例是否可用的测试类
class Example
{
public:
	Example(){value = 0;}
	~Example(){}

	void tool()
	{
		value++;
		std::cout << value<< std::endl;
	}
private:
	int value;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值