设计模式——单例模式

什么是单例模式

一个类只能创建一个对象,即单例模式,该模式下可保证系统中该类只有一个实例,并提供一个访问它的全局接口,该实例被所有程序模块共享。

单例模式有两种实例情况

  • 饿汉模式:程序启动就创建一个唯一的实例对象
  • 懒汉模式:调佣全局接口的时候创建唯一的实例。

饿汉模式

cpp 复制代码
class Singleton
{
public:
	static Singleton* GetInstance()
	{
		return _ins;
	}

	void Add(const string& str)
	{
		_mtx.lock();

		_v.push_back(str);

		_mtx.unlock();
	}

	void Print()
	{
		_mtx.lock();

		for (auto& e : _v)
		{
			cout << e << endl;
		}
		cout << endl;

		_mtx.unlock();
	}

private:
	//限制类外随意创建对象
	Singleton()
	{

	}

private:
	int _n;
	vector<string> _v;
	mutex _mtx;

	static Singleton* _ins;
};

Singleton* Singleton::_ins = new Singleton;

但是饿汉有一个问题:如果单例对象十分耗时或者占用很多资源,比如加载插件,初始化网络连接,也有可能在程序一开始用不到,那么在程序一开始创建就会导致程序启动很慢,所以有了懒汉模式。

懒汉模式

cpp 复制代码
class Singleton
{
public:
	static Singleton* GetInstance()
	{
		//双检查加锁
		if (_ins == nullptr) //提高效率,不需要每次加锁和解锁 
		{
			_imtx.lock();
			
			if (_ins == nullptr) //保证线程安全,只用new一次
			{
				_ins = new Singleton;
			}

			_imtx.unlock();
		}

		return _ins;
	}

	void Add(const string& str)
	{
		_vmtx.lock();

		_v.push_back(str);

		_vmtx.unlock();
	}

	void Print()
	{
		_vmtx.lock();

		for (auto& e : _v)
		{
			cout << e << endl;
		}
		cout << endl;

		_vmtx.unlock();
	}

private:
	//限制类外随意创建对象
	Singleton()
	{

	}

private:
	int _n;
	vector<string> _v;
	mutex _vmtx;

	static mutex _imtx;
	static Singleton* _ins;
};
 
Singleton* Singleton::_ins = nullptr;
mutex Singleton::_imtx;

这里注意一下,创建实例的时候要用双重加锁,因为在多线程的场景下,就去一直加锁判断,要知道锁的消耗是很大的,所以双重检查是很重要的。

懒汉模式的优点:

  • 第一次使用的时候创建实例对象
  • 如果多个单例对象有启动顺序要求的话,也可以控制(这点饿汉模式就无法控制了)

懒汉模式的缺点

  • 复杂
相关推荐
论迹复利3 小时前
FreeRTOS 在 RISC-V 上是如何“点火“的 —— 从 main() 到第一个任务的完整链路
java·开发语言·risc-v
张宇Joaquin3 小时前
鲲鹏统一并行加速库KUPL--众核并行能力介绍
java·开发语言·网络
736c3 小时前
C语言-数组 07
c语言·开发语言
宸津-代码粉碎机4 小时前
AI攻防战升级!基于Spring AI构建Java应用自动免疫安全体系
java·大数据·开发语言·人工智能·python·安全·spring
LorryJovens5 小时前
【LAAP科研】CEN因果等价网络理论---从双缝干涉到因果等价
开发语言·php
Brilliantwxx6 小时前
【Linux】 进程(10) 进程控制深度解析:创建、终止与等待
linux·运维·服务器·c语言·开发语言·网络
码匠许师傅7 小时前
【设计模式精讲】14.外观模式(Facade)
c++·设计模式·uml·外观模式
卢锡荣7 小时前
国产PD3.1全集成Type-C管控芯片LDR6020P
c语言·开发语言
Freak嵌入式7 小时前
Pico UART 数据收发实战:硬件配置、MicroPython 编程
java·开发语言·单片机·嵌入式硬件·生活
Casual7 小时前
【网络基础进阶】:看懂子网划分与 VLAN
开发语言·网络·php