设计模式-------单例模式
2018-03-16 20:51
148 查看
简介
单例模式是最常用的设计模式之一,它属于创建型模式,它提供一种创建对象的最佳方式。保证一个类仅有一个
实例,并提供一个访问它的全局访问点。
单例模式不同的实现方式
1.饿汉模式:class Singleton
{
public:
static Singleton* GetInstance()
{
return instance;
}
private:
Singleton()
{
cout<<"Singleton()"<<endl;
}
static Singleton* instance ;
};
Singleton* Singleton::instance= new Singleton();//静态数据成员必须初始化
int main()
{
cout << "main run..." << endl; //验证静态对象的创建在main之前
Singleton* _s1 = Singleton::GetInstance();
Singleton* _s2 = Singleton::GetInstance();
cout << _s1 << endl;
cout << _s2 << endl;
//返回的是同一个对象
system("pause");
return 0;
}运行结果:
结论:饿汉模式顾名思义就是用空间换时间,并且是线程安全的。
2.懒汉模式class Singleton
{
public:
static Singleton* GetInstance()
{
if (instance == NULL) {
instance = new Singleton();
cout << "Obj success for" << endl;
}
else
cout << "Create failure" << endl;
return instance;
}
private:
Singleton()
{
cout << "Singleton()" << endl;
}
static Singleton* instance;
};
Singleton* Singleton::instance =NULL;//静态数据成员必须初始化
int main()
{
cout << "main run..." << endl; //验证静态对象的创建在main之前
Singleton* _s1 = Singleton::GetInstance();
Singleton* _s2 = Singleton::GetInstance();
cout << _s1 << endl;
cout << _s2 << endl;
//返回的是同一个对象
system("pause");
return 0;
}
运行结果:
结论:懒汉模式用饿汉模式相反,它是用时间换取空间,但线程不安全。
3.带双重检查的懒汉模式class Singleton
{
public:
volatile static Singleton* GetInstance()
{
//第一次检查实例是否存在
if (instance == NULL)
{
lock_guard<mutex> lock(_mtx);//调用即加锁,离开大括号作用域自动解锁
//第二次检查实例是否存在
if (instance == NULL)
{
instance = new Singleton();
cout << "Obj success for" << endl;
}
else
cout << "Create failure" << endl;
}
return instance;
}
private:
Singleton()
{
cout << "Singleton()" << endl;
}
volatile static Singleton* instance; //设置volatile关键字,防止被编译器优化
static mutex _mtx;
};
volatile Singleton* Singleton::instance = NULL;//静态数据成员必须初始化
mutex Singleton::_mtx;
int main()
{
cout << "main run..." << endl; //验证静态对象的创建在main之前
volatile Singleton* _s1 = Singleton::GetInstance();
volatile Singleton* _s2 = Singleton::GetInstance();
cout << _s1 << endl;
cout << _s2 << endl;
//返回的是同一个对象
system("pause");
return 0;
}
运行结果:
结论:先解释下为什么在同步块内还要再检验一次,因为可能会有多个线程一起进入同步块外的 if,如果在同步块内不进行二次检验的话就会生成多个实例了。这种实现版本,不仅安全且在多线程情况下能保持高性能。
单例模式是最常用的设计模式之一,它属于创建型模式,它提供一种创建对象的最佳方式。保证一个类仅有一个
实例,并提供一个访问它的全局访问点。
单例模式不同的实现方式
1.饿汉模式:class Singleton
{
public:
static Singleton* GetInstance()
{
return instance;
}
private:
Singleton()
{
cout<<"Singleton()"<<endl;
}
static Singleton* instance ;
};
Singleton* Singleton::instance= new Singleton();//静态数据成员必须初始化
int main()
{
cout << "main run..." << endl; //验证静态对象的创建在main之前
Singleton* _s1 = Singleton::GetInstance();
Singleton* _s2 = Singleton::GetInstance();
cout << _s1 << endl;
cout << _s2 << endl;
//返回的是同一个对象
system("pause");
return 0;
}运行结果:
结论:饿汉模式顾名思义就是用空间换时间,并且是线程安全的。
2.懒汉模式class Singleton
{
public:
static Singleton* GetInstance()
{
if (instance == NULL) {
instance = new Singleton();
cout << "Obj success for" << endl;
}
else
cout << "Create failure" << endl;
return instance;
}
private:
Singleton()
{
cout << "Singleton()" << endl;
}
static Singleton* instance;
};
Singleton* Singleton::instance =NULL;//静态数据成员必须初始化
int main()
{
cout << "main run..." << endl; //验证静态对象的创建在main之前
Singleton* _s1 = Singleton::GetInstance();
Singleton* _s2 = Singleton::GetInstance();
cout << _s1 << endl;
cout << _s2 << endl;
//返回的是同一个对象
system("pause");
return 0;
}
运行结果:
结论:懒汉模式用饿汉模式相反,它是用时间换取空间,但线程不安全。
3.带双重检查的懒汉模式class Singleton
{
public:
volatile static Singleton* GetInstance()
{
//第一次检查实例是否存在
if (instance == NULL)
{
lock_guard<mutex> lock(_mtx);//调用即加锁,离开大括号作用域自动解锁
//第二次检查实例是否存在
if (instance == NULL)
{
instance = new Singleton();
cout << "Obj success for" << endl;
}
else
cout << "Create failure" << endl;
}
return instance;
}
private:
Singleton()
{
cout << "Singleton()" << endl;
}
volatile static Singleton* instance; //设置volatile关键字,防止被编译器优化
static mutex _mtx;
};
volatile Singleton* Singleton::instance = NULL;//静态数据成员必须初始化
mutex Singleton::_mtx;
int main()
{
cout << "main run..." << endl; //验证静态对象的创建在main之前
volatile Singleton* _s1 = Singleton::GetInstance();
volatile Singleton* _s2 = Singleton::GetInstance();
cout << _s1 << endl;
cout << _s2 << endl;
//返回的是同一个对象
system("pause");
return 0;
}
运行结果:
结论:先解释下为什么在同步块内还要再检验一次,因为可能会有多个线程一起进入同步块外的 if,如果在同步块内不进行二次检验的话就会生成多个实例了。这种实现版本,不仅安全且在多线程情况下能保持高性能。
相关文章推荐
- 设计模式之简单工厂模式
- C#软件设计——小话设计模式原则之:接口隔离原则ISP
- (1)Java设计模式-工厂方法模式(Factory Method)
- Java架构中的常见设计模式
- 设计模式之中介者模式_动力节点Java学院整理
- [设计模式]命令模式
- Java设计模式:命令模式(Command)
- 【U3D设计模式】单例模式
- 多线程设计模式之Future模式
- JAVA23种设计模式
- 设计模式--简单工厂
- 设计模式——单例模式
- 设计模式大类--创建模式
- 黑马程序员--字符流缓冲区对象,装饰设计模式,字节流,字节流的缓冲区对象,转换流对象
- C++设计模式实例图解
- 设计模式
- 设计模式之三重定义——重载,重写,重构
- 学习设计模式 (四)(总结)
- 简单工厂和单例设计模式
- 设计模式之建造者模式用例