@(设计模式)[设计模式, C++实现]
一个很容易想到的单例模式的实现: 构造函数声明为private或protected,防止外部函数将其实例化,内部保存一个private static类指针保存唯一的实例,再由一个public函数返回该实例。
class singleton { protected: singleton(){} private: static singleton* p; public: static singleton* instance(); }; singleton* singleton::p = NULL; singleton* singleton::instance() { if (p == NULL) p = new singleton(); return p; }该实现简单易懂,但是并不是线程安全的单例模式,因为假如两个线程同时调用instance()函数,同时发现p==NULL,并同时构造一个新的实例并赋值给p,这样不仅实现了两个实例,还让两个线程获得了不同的实例,显然是错误的。
懒汉的单例模式:不到迫不得已就不去实例化类,也就是第一次调用的时候才会实例化类(上面的实现也是懒汉单例模式)。
想实现线程安全的单例模式由两种办法:1.加锁,2.使用内部静态变量
也就是对p加锁,防止同时访问。
class singleton { protected: singleton() { pthread_mutex_init(&mutex); } private: static singleton* p; public: static pthread_mutex_t mutex; static singleton* initance(); }; pthread_mutex_t singleton::mutex; singleton* singleton::p = NULL; singleton* singleton::initance() { if (p == NULL) { pthread_mutex_lock(&mutex); if (p == NULL) p = new singleton(); pthread_mutex_unlock(&mutex); } return p; }在instance函数里定义一个静态的实例,也可以保证拥有唯一实例,在返回时只需要返回其指针就可以了。值得注意的是,在C++0X之前,编译器并没有保证内部静态变量的线程安全,所以也需要加锁,但在C++0X之后就不用了。
class singleton { protected: singleton() { pthread_mutex_init(&mutex); } public: static pthread_mutex_t mutex; static singleton* initance(); int a; }; pthread_mutex_t singleton::mutex; singleton* singleton::initance() { pthread_mutex_lock(&mutex);//before C++0X static singleton obj; pthread_mutex_unlock(&mutex);//before C++0X return &obj; }由静态初始化实例保证其线程安全性: 静态实例初始化在程序开始时进入主函数之前就由主线程以单线程方式完成了初始化,不必担心多线程问题。
故在性能需求较高时,应使用这种模式,避免频繁的锁争夺。
class singleton { protected: singleton(){} private: static singleton* p; public: static singleton* initance(); }; singleton* singleton::p = new singleton; singleton* singleton::initance() { return p; }