1、单例模式可以保证系统中一个类只有一个实例。即一个类只有一个实例对象。
有一些对象我们只需要一个,比方说:线程池、缓存、对话框、处理偏好设置和注册表的对象、日志对象、充当打印机、显卡等设备的驱动程序的对象。
事实上,这类对象只能有一个实例,如果制造出多个实例就会导致许多问题的发生。例如:程序行为异常、资源使用过量、或者是不一致的结果。
单例模式分类:饿单例模式(类加载时实例化一个对象给自己的引用),懒单例模式(调用取得实例的方法如getInstance时才会实例化对象)
(java中饿单例模式性能优于懒单例模式,c++中一般使用懒单例模式)
单例模式要素:
a.私有构造方法
b.私有静态引用指向自己实例
c.以自己实例为返回值的公有静态方法
(1)懒汉式:只有在使用的时候才实例化。
class Singleton
{
private:
Singleton();
static Singleton *_instance;
public:
static Singleton *getlntance();
};
Singleton* Singleton::_instance = NULL;
Singleton * Singleton::getlntance()
{
if(_instance == NULL)
{
_instance = new Singleton();
}
return _instance;
}
int main()
{
Singleton *object = Singleton::getlntance();
}
懒汉式在单线程中没有问题,但在多线程中就可能会出现安全问题。
(2)考虑多线程安全问题,使用互斥锁
判断是否是线程安全 —— 是否存在竞态条件
判断是否是竞态条件 —— 随着线程调度顺序的不同,代码执行的结果也会不同
存在竞态条件的代码称为临界区,临界区代码是需要原子操作,实现原子操作使用互斥锁。
class Singleton
{
private:
Singleton();
static Singleton *_instance;
public:
static Singleton *getlntance();
};
Singleton* Singleton::_instance = NULL;
Singleton * Singleton::getlntance()
{
pthread_mutex_lock(&mutex);
if(_instance == NULL)
{
_instance = new Singleton();
}
pthread_mutex_unlock(&mutex);
return _instance;
}
int main()
{
Singleton *object = Singleton::getlntance();
}