单例模式

来源:互联网 发布:ubuntu 安装 ssh 编辑:程序博客网 时间:2024/06/05 09:12

定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

概念上可理解成一个类只有一个实例,实现上是要注意以下三点:

1、单例模式的类只提供私有的构造函数,

2、类定义中含有一个该类的静态私有对象,

3、该类提供了一个静态公有函数用于创建或获取它的静态私有对象

 

单例模式一般有3种写法:饿汉模式、懒汉模式、双重锁定(懒汉模式线程安全的实现方式)

1、饿汉模式是指,在单例类定义的时候就进行实例化。即便是在多线程环境下,也只是访问已经存在的实例,不会出现线程安全问题。

这里需要注意的是,静态成员变量,只能在类外进行初始化,除非,它被const修饰;static修饰符,只是在声明时使用,定义时并不需要。

此处instance()函数就是访问唯一实例的,全局访问点

class singleton{public:static singleton* instance();protected:singleton();private:static singleton* _instance;};singleton* singleton::instance(){return _instance;}singleton::singleton(){}singleton* singleton::_instance = new singleton();

2、懒汉模式是指,在类定义的时候,并不进行实例化。在需要的时候才进行实例化。

此处instance()函数就是访问或创建唯一实例的,全局访问点。考虑多线程环境下,instance()函数存在线程安全问题。

class singleton{public:static singleton* instance();protected:singleton();private:static singleton* _instance;};singleton* singleton::instance(){if (_instance == NULL){_instance = new singleton();}return _instance;}singleton::singleton(){}singleton* singleton::_instance = NULL;
一般使用单例模式的方式是:

singleton *ton = singleton::instance();

3、双重锁定就是针对懒汉模式线程不安全的改进,解决了懒汉模式线程安全问题。

相较于懒汉模式,双重锁定为了避免实例化唯一对象时,出现竞态,因此声明了一个互斥锁,用于实现线程安全。为什么会出现双重判断是否为空。首先,外层判断是否为空是可以去掉的,但是会存在效率问题,实际上一旦_instannce指针实例化,就不会出现竞态,每个线程就不需要再获取锁,释放锁,等待锁了。内层判断是否为空是必须的,因为初始的时候可能多个线程抢占锁,当一个线程释放锁后,另一个线程会获取锁,若没有空判断,会再次创建实例。

singleton* singleton::instance(){if (_instance == NULL){pthread_mutex_lock(&mutex);if (_instance == NULL){_instance = new singleton();}pthread_mutex_unlock(&mutex);}return _instance;}singleton::singleton(){}singleton* singleton::_instance = NULL;