单例模式(附代码)

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; 
posted @ 2022-03-30 16:51  周小鱼丶  阅读(350)  评论(0)    收藏  举报