设计模式之单例

xiaoxiao2021-02-28  57

什么是单例模式? 单例模式(Singleton Parttern)保证一个类仅有一个实例,并提供一个访问它的全局访问点。类似于全局变量,但是效果比全局变量更优,全局变量必须在程序开始就创建,如果后面没有用到,会造成资源的浪费。 为什么要创建单例模式? 有一些对象我们只需要一个,比方说:线程池(threadPool)、缓存(cache)、对话框、注册表(registry)的对象、日志对象,充当打 字机,显卡等设备的驱动程序的对象。事实上,这些对象只能有一个实例,如果创造了过个实例,会导致很多问题,例如:程序的行为异常、资源使用过度,或发生不一致的后果。 单例模式的特点: 单例类只能有一个实例; 单例类必须自己创建这个实例; 单例类必须自行想整个系统提供实例; 单例模式的实现方式: 一般 将 构造函数声明为私有,用一个静态public来实例化对象,返回该类的实例,在外部通过调用这个方法来实例化对象。 一、饿汉式单例类 [cpp] view plain copy print ? //饿汉式单例类在类初始化时自行实例化   class singleton{    private:        static singleton *instance;//用一个静态变量来记录该类的唯一实例        singleton(){};      public:        //返回该类的实例      static singleton* get_instance()        {             return instance;        }    };    singleton* singleton::instance = new singleton();//静态成员变量初始化    //饿汉式单例类在类初始化时自行实例化 class singleton{ private: static singleton *instance;//用一个静态变量来记录该类的唯一实例 singleton(){}; public: //返回该类的实例 static singleton* get_instance() { return instance; } }; singleton* singleton::instance = new singleton();//静态成员变量初始化 二、饱汉(懒汉)式单例类 [cpp] view plain copy print ? class singleton{    private:        static singleton *instance;//用一个静态变量来记录该类的唯一实例        singleton(){};      public:        //返回实例前先检查,如果没有创建,则先创建再返回该类的实例      static singleton* get_instance()        {            if(NULL == instance)  <—两个线程同时运行到这              instance = new singleton();            return instance;        }    };    singleton* singleton::instance = NULL;//静态成员变量初始化    class singleton{ private: static singleton *instance;//用一个静态变量来记录该类的唯一实例 singleton(){}; public: //返回实例前先检查,如果没有创建,则先创建再返回该类的实例 static singleton* get_instance() { if(NULL == instance) <---两个线程同时运行到这 instance = new singleton(); return instance; } }; singleton* singleton::instance = NULL;//静态成员变量初始化 这里有个问题,如果在多线程环境下使用会出现问题,比如两个线程同时运行到代码所指位置,由于最初instance都是初始化为NULL,那么两个线程会同时进入到if里面然后创建出两个实例!这显然与单例模式不符,所以我们要对它进行实例化的代码进行互斥操作。 三、加互斥锁 通过加锁可以实现多个线程判断instance是否为空。 [cpp] view plain copy print ? #include <iostream>    #include <mutex>    using namespace std;    mutex mtx;//互斥锁    class singleton{    private:        static singleton *instance;//利用一个静态变量来记录Singleton的唯一实例        singleton(){};      public:        //实例化对象的方法        static singleton* getInstance()        {            mtx.try_lock();//加锁函数            if(NULL == instance)          {              instance = new singleton();          }          mtx.unlock();//释放锁函数          return instance;        }    };      singleton* singleton::instance = NULL;//静态成员变量初始化     #include <iostream> #include <mutex> using namespace std; mutex mtx;//互斥锁 class singleton{ private: static singleton *instance;//利用一个静态变量来记录Singleton的唯一实例 singleton(){}; public: //实例化对象的方法 static singleton* getInstance() { mtx.try_lock();//加锁函数 if(NULL == instance) { instance = new singleton(); } mtx.unlock();//释放锁函数 return instance; } }; singleton* singleton::instance = NULL;//静态成员变量初始化

四、双重检测加锁 因为我们只需要在没有创建实例时对它进行加锁,如果已经创建实例则不需要再进行加锁操作。所以要在加锁前先判断一次实例是否已经创建。 [cpp] view plain copy print ? mutex mtx;//互斥锁    class singleton{    private:        static singleton *instance;//利用一个静态变量来记录Singleton的唯一实例        singleton(){};      public:        //实例化对象的方法        static singleton* getInstance()        {            if(NULL == instance)          {              mtx.try_lock();//加锁函数                if (NULL == instance)              {                  instance = new singleton();              }              mtx.unlock();//释放锁函数          }          return instance;        }    };      singleton* singleton::instance = NULL;//静态成员变量初始化     mutex mtx;//互斥锁 class singleton{ private: static singleton *instance;//利用一个静态变量来记录Singleton的唯一实例 singleton(){}; public: //实例化对象的方法 static singleton* getInstance() { if(NULL == instance) { mtx.try_lock();//加锁函数 if (NULL == instance) { instance = new singleton(); } mtx.unlock();//释放锁函数 } return instance; } }; singleton* singleton::instance = NULL;//静态成员变量初始化

转自: http://blog.csdn.net/a987073381/article/details/52145711

转载请注明原文地址: https://www.6miu.com/read-97402.html

最新回复(0)