C++用多种方式实现Singleton单例模式

题目:设计一个类,只能生成该类的一个实例。

(1)解法一:只适用于单线程环境

由于要求只能生成一个实例,因此我们必须把构造函数设为私有函数以禁止他人创建实例。我们可以定义一个静态的实例,在需要的时候创建该实例。

public class Singleton1{

  private Singleton1(){
  
  }
  
  private static Singleton1 instance = NULL;
  
  public static Singleton1 funcInstance{
  
    get{
    
      if(instance == NULL){
      
        instance = new Singleton1();
      }
     
      return instance;
      
    }
  }

  
}

上述代码在Singleton1的静态方法funcInstance()中,只有在instance为null的时候才创建一个实例以避免重复创建,同时把构造函数定义为私有函数,这样才能确保只创建一个实例。



(2)解法二:虽然能在多线程环境中能工作但是效率不高

解法一中的代码在单线程的时候工作正常,但是在多线程的情况下就有问题了。假设两个线程同时运行到判断instance是否为null的if语句,并且instance的确没有创建时,那么两个线程都会创建一个实例,此时就不再满足单例模式的要求了。

为了保证在多线程环境下我们还是只能得到类型的一个实例,需要加上一个同步锁。实现如下:

public class Singleton2{

  private Singleton2(){
  
  }
  
  private static readonly object syncObj = new object();
  
  private static Singleton2 instance = NULL;
  
  public static Singleton2 funcInstance{
  
    get{
      
      lock(sync){
      
        if(instance == NULL){
          
          instance = new Singleton2();
        }
        
      }
      
      return instance;
      
    }
  }

  
}

我们还是假设有两个线程同时想创建一个实例。由于在一个时刻只有一个线程能得到同步锁,当第一个线程加上锁时,第二个线程只能等待。当第一个线程发现实例还没有创建时,他创建出一个实例。接着第一个线程释放同步锁,此时第二个线程可以加上同步锁,并运行接下来的代码。这个时候由于实例已经被第一个线程创建出来了,第二个线程就不会重复创建实例了。但是加锁是一个比较耗时的操作,我们应该尽量避免。


(3)解法三:加同步锁前后两次判断实例是否已存在

我们只是在实例还没有创建之前需要加锁操作,以保证只有一个线程创建出实例。而当实例已经创建之后,就不需要加锁操作了。代码实现如下:

public class Singleton3{

  private Singleton3(){
  
  }
  
  private static readonly object syncObj = new object();
  
  private static Singleton3 instance = NULL;
  
  public static Singleton3 funcInstance{
  
    get{
      
      if(instance == NULL){
      
        lock(sync){
          
          if(instance == NULL){
            
            instance = new Singleton3();
          }
          
        }
        
      }
      
      return instance;
      
    }
  }

  
}

Singleton3中只有当instance为NULL即没有创建时,需要加锁操作。当instance已经创建出来后,则无需加锁。因为只有第一次的时候instance为NULL,因此只有在第一次试图创建实例的时候需要加锁,这样Singleton3的时间效率就比Singleton2好。


github主页:https://github.com/chenyufeng1991  。欢迎大家访问!





















  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值