饿汉模式与懒汉模式

单例模式:
一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全 局访问点,该实例被所有程序模块共享。比如在某个服务器程序中,该服务器的配置信息存放在一个文件 中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置 信息,这种方式简化了在复杂环境下的配置管理。
单例模式有两种实现模式:
饿汉模式

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

优点:简单 

缺点:可能会导致进程启动慢,且如果有多个单例类对象实例启动顺序不确定。 

用c++实现饿汉模式的封装流程如下:

class Singleton 
{
public:    
	static Singleton* GetInstance()      
	{ 
		return &m_instance; 
	}    private:     // 构造函数私有    
		Singleton(){};        // C++98 防拷贝   
		Singleton(Singleton const&);     
		Singleton& operator=(Singleton const&);           // or          // C++11  
		Singleton(Singleton const&) = delete;    
		Singleton& operator=(Singleton const&) = delete;      
		static Singleton m_instance; 
};    
Singleton Singleton::m_instance;  // 在程序入口之前就完成单例对象的初始化

如果这个单例对象在多线程高并发环境下频繁使用,性能要求较高,那么显然使用饿汉模式来避免资源竞 争,提高响应速度更好。

懒汉模式

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

 懒汉 

优点:第一次使用实例对象时,创建对象。进程启动无负载。多个单例实例启动顺序自由控制。 

缺点:复杂

c++实现模式代码如下:

#include <iostream>
#include <mutex>
#include <thread>
using namespace std;

class Singleton {
public:    
	static Singleton* GetInstance() 
	{      
		// 注意这里一定要使用Double-Check的方式加锁,才能保证效率和线程安全     
			   if (nullptr == m_pInstance) {           
				   m_mtx.lock();       
				   if (nullptr == m_pInstance) { 
			   m_pInstance = new Singleton();
				}           
					m_mtx.unlock();
				}       
			   return m_pInstance;   
	}// 实现一个内嵌垃圾回收类       
	class CGarbo {   
	public:        
		~CGarbo()
		{           
			if (Singleton::m_pInstance)               
				delete Singleton::m_pInstance;      
		}    
	};

// 定义一个静态成员变量,程序结束时,系统会自动调用它的析构函数从而释放单例对象    
	static CGarbo Garbo;

private:   
	// 构造函数私有  
	Singleton(){};

	// 防拷贝    
	Singleton(Singleton const&);   
	Singleton& operator=(Singleton const&);

	static Singleton* m_pInstance; // 单例对象指针   
	static mutex m_mtx;            //互斥锁 };

	Singleton* Singleton::m_pInstance = nullptr; Singleton::CGarbo Garbo; mutex Singleton::m_mtx;

	void func(int n) { cout << Singleton::GetInstance() << endl;
	}

	// 多线程环境下演示上面GetInstance()加锁和不加锁的区别。
	int main() {    
		thread t1(func, 10);    thread t2(func, 10);

		t1.join();    t2.join();

	cout << Singleton::GetInstance() << endl;    cout << Singleton::GetInstance() << endl;
}


 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值