单例模式(附代码)
1.单例模式:一个类只有一个对象的场景
单例模式分为:
1. 饿汉模式
2. 懒汉模式
3. 多线程模式
单例模式需要满足:
1.一个类只产生一个实例
2.提供一个对该实例全局访问的指针
3.客户端是单例类,但不影响以后有多个实例
判断饿汉和懒汉:
饿汉:运行到自己时,就将自己实例化一个对象,所以很饿。因为程序一运行,就生成实力对象,所以不存在线程安全的问题
懒汉:只有当第一次调用类中的函数GetInstance()时,才会实例化一个对象,就是说只有需要的时候才调用这个函数产生对象,所以很懒。并且存在线程安全问题,多个进程调用该函数,就会导致实例化多个对象。所以要加锁
2.饿汉模式:
class Singleton(){
private:
Sinleton(){}; //私有化构造函数,使得外部无法直接实例化得到一个对象
static Singleton* P_Hungry; //静态指针指向唯一对象
public:
static Singleton* GetInstance(){
return P_Hungry;
}
}
Singleton* Singleton::P_Hungry =new Singleton();
//static变量类外 实例化,调用构造函数,分配了对象的空间
//表现得很急,还没有调用类中的GetInstance(),已经将这个类的对象实例化出来,P_Hungry 指向该对象
3. 懒汉模式:
class Singleton(){
private:
Sinleton(){}; //私有化构造函数,使得外部无法直接实例化得到一个对象
static Singleton* P_Lazy;
public:
static Singleton* GetInstance(){
if(P_Lazy == NULL){
P_Lazy = new Singleton(); //只有当调用这个GetInstance()函数时,才实例化一个对象,P_Lazy指向该对象
}
return P_Lazy;
}
}
Singleton* Singleton::P_Lazy =NULL;
//static变量类外 初始化,没有调用构造函数,只是给指针分配了空间,对象没有实例化
4.多线程单例模式(解决懒汉模式线程安全的问题)
//解法1
class Singleton(){
private:
Sinleton(){}; //私有化构造函数,使得外部无法直接实例化得到一个对象
static Singleton* P_Lazy;
static Lock lock();
public:
static Singleton* GetInstance(){
lock();
if(P_Lazy == NULL){
P_Lazy = new Singleton();
unlock();
}
return P_Lazy;
}
}
Singleton* Singleton::P_Lazy =NULL;
解法1通过加锁,使得两个进程只有一个能实例化对象,满足单例模式条件
但是另一个未实例化对象的进程,不死心,也会执行类函数,又会加一次锁,加锁过程很麻烦耗时,所以提供解法1的进阶解法
即:需要加两个if(P_Lazy == NULL),避免线程堵塞
//进阶解法1
class Singleton(){
private:
Sinleton(){}; //私有化构造函数,使得外部无法直接实例化得到一个对象
static Singleton* P_Lazy;
static Lock lock();
public:
static Singleton* GetInstance(){
if(P_Lazy == NULL){ //只有无实例化,才会上锁
lock();
if(P_Lazy == NULL){
P_Lazy = new Singleton();
}
unlock();
}
return P_Lazy;
}
}
Singleton* Singleton::P_Lazy =NULL;
本文来自博客园,作者:{author 周小鱼},转载请注明原文链接:https://www.cnblogs.com/zhouxiaoyu16/p/16077862.html

浙公网安备 33010602011771号