设计模式——单例模式

什么是单例模式

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

单例模式有两种实例情况

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

饿汉模式

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 小时前
【C++】AVL 树
c++
wuminyu4 小时前
JVM规范学习总结:解释器与JIT编译器如何处理JVM字节码
java·linux·c语言·jvm·c++
小徐不徐说4 小时前
序列化与反序列化:把 C++ 对象可靠地保存下来
开发语言·数据库·c++·php
ragnwang4 小时前
Notes: Python pybind11 import C++ module
开发语言·c++·python
Wang's Blog4 小时前
Java 项目实战: 交友项目 - 搜索附近的功能概述和分析
java·开发语言·交友
骑着蜗牛撵大象3275 小时前
大模型 Agent 的沙箱护栏:gVisor 隔离、出口白名单与审计闭环
java·开发语言·jvm·安全·agent沙箱·gvisor·microvm
Dxy12393102166 小时前
JS DES 加密详解
开发语言·javascript·arcgis
充值内卷6 小时前
我给桌面加了个鱼缸:C++ 写后端,WebView2 里养一座 Three.js 小岛
开发语言·javascript·c++
云和数据.ChenGuang6 小时前
深入解析 Python 的 dir():从用法到 CPython 源码实现
开发语言·人工智能·python·langchain
nice_lcj5207 小时前
深入理解 Java 反射:从 Class 对象到方法调用(含性能实测 + 迷你 IOC 实战 + 面试考点)
java·开发语言·后端·面试