剑指offer---实现Singleton模式(2)


Singleton模式:只能生成一个实例的类是实现了Singleton模式的类型

快加载:未调用创建对象的函数时,已经为对象分配好内存,以及初始化。

class Singleton
{
public:
    static Singleton* getmySingleton()
    {
            return &mySingleton;
    }
private:
    Singleton()  { };         
    static Singleton mySingleton;
};
Singleton Singleton::mySingleton;


快加载是线程安全的,因为在main函数之前,要进行对static变量进行初始化,因此多线程不论怎样调度都是返回的是同一个对象。

懒加载:在调用创建对象的时候,才给开辟内存,构造对象

class Singleton
{
public:
    static Singleton* getSingleton()
    {
        if(mySingleton == NULL)
        {
            pthread_mutex_lock(&mutex);
            if(mySingleton == NULL)
            {
                mySingleton = new Singleton();
            }
            pthread_mutex_unlock(&mutex);
        }
        return &mutex;
    }
private:
    Singleton() { }
    static pthread_mutex mutex;
    static volatile Singleton* mySingleton;
    ~Singleton()  { pthread_mutex_destroy(&mutex,NULL); delete mySingleton}
};
pthread_mutex Singleton::mutex = PTHREAD_MUTEX_INITIALIZER;
Singleton* Singleton::mySingleton = NULL;


在这里解释两个东西:
一、进行双重锁机制的原因
当线程1运行到加锁完成时,线程2现在抢占cpu也要进行加锁,然后进行阻塞,进而1线程完成了对象的创建,并且释放了锁。现在线程2现在立即加锁成功,进行对象的创建,则出现错误,对对象指针进行了二次new。二次锁则很有效率的解决了这个问题。

二、volatiled的作用
如果cpu将mySingleton读取到高速缓冲区当中,当线程1对mySingleton进行new之后,还未写回内存,只是写入到了缓冲区当中。那么线程2读取的mySingleton 为NULL,继续对mySingleton 进行new,则会出错。
而volatile声明的变量,当cpu要读取或者写入mySingleton 时都会直接从内存上进行访问,不会对mySingleton 进行缓存。


可以对锁进行封装,提高代码的便捷性

class CMutex             //对锁进行封装
{
public:
   CMutex()
  {
     pthread_mutex_init(&mutex,NULL);
   }
  ~CMutex()
   {
     pthread_mutex_destroy(&mutex);
   }
   void lock()
   {
      pthread_mutex_lock(&mutex);
    }
   void unlock()
   {
      pthread_mutex_unlock(&mutex);
    }
private:
  pthread_mutex_t mutex;
};  


class  SingleTon
{
public:
   static SingleTon * getInstance()
    {      
        if(mpSingleTon == NULL)
         {  
            mutex.lock();                               //将加锁解锁放在if语句内是为了保证在单线程下程序执
            if(mpSingleTon == NULL)??????????                                               行的效率。
            mpSingleTon = new SingleTon ();
            mutex.unlock();
         }
        return &SingleTon 
     }
  private:
  SingleTon(){};
  ~SingleTon(){};
   static CMutex mutex;
  static volatile SingleTon *mpSingleTon;      //告诉操作系统  mpSingleTon是一个异变的变量。操作时直接
                                               从内存上(read/write)      
}
CMutex SingleTon::mutex;
SingleTon * SingleTon ::mpSingleTon = NULL;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值