设计模式6---(单例模式的概念及其实现(懒汉式和饿汉式),线程安全)

单例模式

单例模式的概念

单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象。也就是说,在整个程序空间中,该类只存在一个实例对象。
GoF 对单例模式的定义是:保证一个类、只有一个实例存在,同时提供能对该实例加以访问的全局访问方法。
在这里插入图片描述

为什么适用单例模式

在应用系统开发中,我们常常有以下需求:

  1. 在多个线程之间,比如初始化一次 socket 资源;比如 servlet 环境,共享同一个资源或者 操作同一个对象
  2. 在整个程序空间使用全局变量,共享资源
  3. 大规模系统中,为了性能的考虑,需要节省对象的创建时间等等。

实现单例步骤常用步骤

  1. 构造函数私有化
  2. 提供一个全局的静态方法(全局访问点)
  3. 在类中定义一个静态指针,指向本类的变量的静态变量指针

懒汉式实现

如果单例对象构造十分耗时或者占用很多资源,比如加载插件啊, 初始化网络连接啊,读取文件啊等等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就进行初始化,就会导致程序启动时非常的缓慢。 所以这种情况使用懒汉模式(延迟加载)更好

//懒汉式,需要才创建
class Singleton_lazy{
private:
	Singleton_lazy(){}
	//防拷贝
	Singleton_lazy(Singleton const&);
	Singleton_lazy & operator=(Singleton const&);
public:
	static Singleton_lazy *getInstace()	//提供方法获取
	{
		if(nullptr == pSingleton) //其它线程看到指针不为空,说明已创建,直接用,不需要再等待
		{
			m_mtx.lock(); //加锁保证线程安全
			if (pSingleton == NULL){
				pSingleton = new Singleton_lazy;//new有可能失败,抛出异常造成死锁
			}
			m_mtx.unlock();
			return pSingleton;
		}
	}
	//内嵌垃圾回收类 RAII的思想
	class Garbo{
    		~Garbo(){
    			if (pSingleton != NULL){
    				delete pSingleton;
    			}
    		}
    	};
private:
	static Singleton_lazy * pSingleton;//类外初始化好
	static mutex m_mtx; //互斥锁
};
//类外初始化
volatile Singleton_lazy * Singleton_lazy::pSingleton = NULL;
Singleton_lazy ::CGarbo Garbo;
mutex Singleton::m_mtx;

编译器有可能进行优化:指令的重排
可以加上volatile

本来的顺序
  1. 申请空间
  2. 构造对象
  3. 赋值
优化的顺序
  1. 申请空间
  2. 赋值
  3. 构造对象

饿汉式实现

就是说不管你将来用不用,程序启动时就创建一个唯一的实例对象。

 //饿汉式,比较着急
    class Singleton_hungry{
    private:
    	Singleton_hungry(){
    	}
    	//防止拷贝
    	Singleton_hungry(Singleton const&);
		Singleton_hungry& operator=(Singleton const&);
    public:
    	static Singleton_hungry *getInstace()
    	{
    		return 	pSingleton;
    	}
	//实现内嵌垃圾回收类
    #if 0
    	class Garbo{
    		~Garbo(){
    			if (pSingleton != NULL){
    				delete pSingleton;
    			}
    		}
    	};
    #endif
    private:
    	static Singleton_hungry * pSingleton;
    };
    Singleton_hungry * Singleton_hungry::pSingleton = new Singleton_hungry;

线程安全

  1. 饿汉式是线程安全的,在main函数前创建对象
  2. 懒汉式不是线程安全的
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值