C# 单例模式的实现和性能对比

简介

单例指的是只能存在一个实例的类(在C#中,更准确的说法是在每个AppDomain之中只能存在一个实例的类,它是软件工程中使用最多的几种模式之一。在第一个使用者创建了这个类的实例之后,其后需要使用这个类的就只能使用之前创建的实例,无法再创建一个新的实例。通常情况下,单例会在第一次被使用时创建。本文会对C#中几种单例的实现方式进行介绍,并分析它们之间的线程安全性和性能差异。

单例的实现方式有很多种,但从最简单的实现(非延迟加载,非线程安全,效率低下),到可延迟加载,线程安全,且高效的实现,它们都有一些基本的共同点:

. 单例类都只有一个private的无参构造函数
. 类声明为sealed(不是必须的)
. 类中有一个静态变量保存着所创建的实例的引用
. 单例类会提供一个静态方法或属性来返回创建的实例的引用(eg.GetInstance) 

几种实现

一. 非线程安全

//Bad code! Do not use!
public sealed class Singleton
{private static Singleton instance = null;private Singleton(){}public static Singleton instance{get{if (instance == null){instance = new Singleton();}return instance;}}
} 

这种方法不是线程安全的,会存在两个线程同时执行if (instance == null)并且创建两个不同的instance,后创建的会替换掉新创建的,导致之前拿到的reference为空。

二. 简单的线程安全实现

public sealed class Singleton
{private static Singleton instance = null;private static readonly object padlock = new object();Singleton(){}public static Singleton Instance{get{lock (padlock){if (instance == null){instance = new Singleton();}return instance;}}}
} 

相比较于实现一,这个版本加上了一个对instance的锁,在调用instance之前要先对padlock上锁,这样就避免了实现一中的线程冲突,该实现自始至终只会创建一个instance了。但是,由于每次调用Instance都会使用到锁,而调用锁的开销较大,这个实现会有一定的性能损失。

注意这里我们使用的是新建一个private的object实例padlock来实现锁操作,而不是直接对Singleton进行上锁。直接对类型上锁会出现潜在的风险,因为这个类型是public的,所以理论上它会在任何code里调用,直接对它上锁会导致性能问题,甚至会出现死锁情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
单例模式和多例模式是设计模式中的两种常见实现方式。 单例模式是一种创建对象的模式,它保证一个类只有一个实例,并提供一个全局访问点来访问该实例。在C#中,可以通过使用静态变量和私有构造函数来实现单例模式。以下是一个示例: ```csharp public class Singleton { private static Singleton instance; private Singleton() {} // 私有构造函数 public static Singleton Instance { get { if (instance == null) { instance = new Singleton(); } return instance; } } } ``` 使用单例模式可以确保在整个应用程序中只有一个实例存在,并且可以通过`Singleton.Instance`来访问该实例。 多例模式是一种可以创建有限个数实例的模式,它保证一个类最多只有指定个数的实例,并提供一个全局访问点来访问这些实例。在C#中,可以使用类似于单例模式的方式来实现多例模式,只需稍作修改即可。以下是一个示例: ```csharp public class Multiton { private static Dictionary<string, Multiton> instances = new Dictionary<string, Multiton>(); private Multiton() {} // 私有构造函数 public static Multiton GetInstance(string key) { if (!instances.ContainsKey(key)) { // 创建新实例并添加到字典中 instances[key] = new Multiton(); } return instances[key]; } } ``` 使用多例模式可以创建指定个数的实例,并且可以通过`Multiton.GetInstance(key)`来访问这些实例,其中`key`是用于区分不同实例的标识符。 这是单例模式和多例模式的简单介绍,它们在实际开发中有各自的应用场景,具体使用哪种模式取决于实际需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值