设计模式之单例模式

单例模式(SingleTon):保证一个类只有一个实例,并提供一个访问它的全局访问点。

由类自身负责保存它的唯一实例,并且保证没有其他实例可以被创建,而不是外部判断。

单例模式结构图

  • C++ 实现
class SingleTon {
private:
	SingleTon() {
		std::cout << "constructor called!" << std::endl;
	}
	SingleTon(SingleTon&) = delete;
	SingleTon& operator=(const SingleTon&) = delete;
	static SingleTon* instance;
public:
	~SingleTon() {
		std::cout << "destructor called!" << std::endl;
	}
	static SingleTon* GetInstance() {
		if (instance == nullptr) {
			instance = new SingleTon;
		}
		return instance;
	}
};
SingleTon* SingleTon::instance = nullptr;     // 懒汉单例
/*SingleTon* SingleTon::intance = new SingleTon ;* // 饿汉单例
  • 利用局部静态变量,实现更简洁的单例模式(懒汉模式)
class SingleTon {
private:
	SingleTon() {
		std::cout << "constructor called!" << std::endl;
	}
	SingleTon(SingleTon&) = delete;
	SingleTon& operator=(const SingleTon&) = delete;

public:
	~SingleTon() {
		std::cout << "destructor called!" << std::endl;
	}
	static SingleTon* GetInstance() {
		static SingleTon instance;
		return &instance;
	}
};

懒汉模式:在第一次使用的时候创建唯一实例。
饿汉模式:在自己被加载的时候将自己实例化,不管是否使用,先创建唯一实例。以后只需要返回唯一实例,这样也是线程安全的。

线程安全的单例模式

简单的单例模式在多线程访问的时候,可能产生多少实例。我们给进程加锁来避免资源竞争,保证只产生一个实例。
当线程位于代码临界区,确保其他线程不能进入临界区,一直等待直到互斥量被释放。


class SingleTon {
private:
	SingleTon() {
		std::cout << "constructor called!" << std::endl;
	}
	SingleTon(SingleTon&) = delete;
	SingleTon& operator=(const SingleTon&) = delete;
	static SingleTon* instance;
	static std::mutex mutex;
public:
	~SingleTon() {
		std::cout << "destructor called!" << std::endl;
	}
	static SingleTon* GetInstance() {
		if (instance == nullptr) { //已经创建实例后直接返回对象,避免每次都加锁
			std::unique_lock<std::mutex> lck(mutex); //上锁,避免多线程竞争
			if (instance == nullptr) { //再次判断,保证多个线程几乎同时到达临界区,也只创建一个实例
				instance = new SingleTon;
			}
		}
		return instance;
	}
};
SingleTon* SingleTon::instance = nullptr;     // 懒汉模式
std::mutex SingleTon::mutex;

代码使用“双重锁定Double-Check Locking”:不让每个线程都加锁,只有在实例未创建的时候加锁,同时也能保证线程安全。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值