单例模式:懒汉式和饿汉式

目录

懒汉模式和饿汉模式

区别

示例

懒汉模式线程不安全

懒汉模式线程安全

 懒汉模式内部静态变量线程安全

饿汉式线程安全


指的是在系统生命周期内,只产生一个实例。

懒汉模式和饿汉模式

分为懒汉式饿汉式

区别

  • 创建时机和线程安全

线程安全:多线程共享资源的过程中,线程安全通过同步机制保证各个线程正确执行。

懒汉式,比较懒,只有在用到的时候才去想我怎么才能用到,所以只有当要用到该对象时才去创建实例。线程不安全

原因:懒汉式的实例是在使用的时候才去申请,这个时候如果还没有new 出来实例,恰好又有多个线程进来访问创建对象的话,就会有问题。

解决方法:加锁。

饿汉式,害怕自己饿着,所以在一开始就准备好自己需要的东西。所以是一运行程序,就创建实例。在线程还未创建之前就已经创建出了实例,所以一定是线程安全的。

  • 执行效率

懒汉式,为保证线程安全,需要加同步锁,所以执行比饿汉式要慢一些。

  • 内存使用

懒汉式,在需要的时候才去创建实例对象,不浪费内存;

饿汉式,一开始就去创建,会占据空间,浪费内存。

示例

懒汉模式线程不安全

//懒汉模式:线程不安全
SingleCase * SingleCase::m_SingleCase = NULL;

SingleCase * SingleCase::GetInstance()
{
	if (m_SingleCase == NULL)
	{
		m_SingleCase = new SingleCase();
	}
	return m_SingleCase;
}

创建5个线程,运行结果:

构造了三次,线程不安全,适合单线程使用

注:可以将构造、析构、拷贝赋值和拷贝构造都改为private,禁止其他类进行操作。

懒汉模式线程安全

//懒汉模式,线程安全
SingleCase * SingleCase::m_SingleCase = NULL;
std::mutex SingleCase::m_mutex;
SingleCase * SingleCase::GetInstance()
{
	if(m_SingleCase == NULL)
	{
        //双检锁
		//假如线程1和线程2同时到达
		m_mutex.lock();
		//此时线程1进入,判断m_SingleCase为空
		if (m_SingleCase == NULL)
		{
			//实例化对象
			m_SingleCase = new SingleCase();
		}
		//结束后,释放锁,此时线程2进入,m_SingleCase已经被实例化,可以避免多次实例
		m_mutex.unlock();
	}
	
	return m_SingleCase;
}

双检锁

1.第一层if判断,完成实例化之后,之后的线程不需要进入等待,提高了效率;

2.第二层if判断,防止对象被多次实例化。

运行结果:

懒汉模式内部静态变量线程安全

//懒汉模式内部静态
SingleCase & SingleCase::GetInstance()
{
	static SingleCase single;
	return single;
}

运行结果:

饿汉式线程安全

SingleCase * SingleCase::m_SingleCase = new SingleCase();
SingleCase * SingleCase::GetInstance()
{
	return m_SingleCase;
}

运行结果:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值