Singleton模式中的DoubleCheck机制

本文探讨了在多线程环境下,如何利用Singleton模式的Double Check机制保证对象实例的唯一性和线程安全。通过分析不同版本的getInstance方法,强调了避免多次实例化和性能优化的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Singleton模式中的DoubleCheck机制

   在多线程环境下,使用Singleton模式很重要的一点就是要保证用Double Check机制保证线程安全。

  很多时候, 我们通常需要使用singleton模式来保证对象实例的唯一性。通常我们是这么写的:

  class Singleton

  {

  private:

  static Singleton *instance;

  public:

  static Singleton* getInstance();

  private:

  Singleton();//将构造函数设为Private以保证只能通过getInstance获取对象实例.

  };

  Singleton *Singleton::instance = NULL;

  //版本一:

  Singleton* Singleton::getInstance()

  {

  if(NULL == instance) //检查是否已经生成对象了

  {

  //对象构造区域

  instance = new Singleton();

  }

  return instance;

  }

  Singleton::Singleton()

  {

  //initializing...

  }

  然而,如果在多线程环境下,Singleton::getInstance() 同时被多个线程调用,也许第一个线程在通过if(NULL == instance)语句后被中断挂起,这时其它线程也会进入该区域,这时instance = new Singleton();语句就会被调用两次或者更多,违背了singleton模式的初衷。为了保证对象构造区域为一个互斥区间,这时我们考虑引入 mutex互斥信号变量。比如:来源:-

   //版本2:

  Singleton* Singleton::getInstance()

  {

  lock(mutex);

  if(NULL == instance) ////检查是否已经生成对象了

  {

  //对象构造区域

  instance = new Singleton();

  }

  release(mutex);

  return instance;

  }

  现在看起来已经足够安全了,只可能同时有一个线程进入对象构造区域。

  此时出现了一个性能问题,每次调用getInstance方法时都需要执行lock(mutex)与release(mutex)的操作,而事实上第一次调用之后,instance就不是NULL值了。

  这时候我们就设计一个Double Check的机制:

  //版本三:

  Singleton* Singleton::getInstance()

  {

  if(NULL == instance)

  {

  //对象实例第一次被创建后, 没有线程会进入该区域了, 因此该版本的性能与版本一几乎相同,且安全性与版本二一样好

  lock(mutex);

  if(NULL == instance) //检查对象是否已经存在

  {

  //对象构造区域

  instance = new Singleton();

  }

  release(mutex);

  }

  return instance;

  }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值