全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

C#单例模式(Singleton Pattern)详解

(新手写博客,主要是对自己学习的归纳总结。会对很多小细节详解。)

单例模式的定义:

确保一个类只有一个实例,并提供一个全局访问点。

首先实例大家应该都明白就是类生成对象的过程简单的就是String s=new String(),则s就是个实例。

Q:如何只生成一个实例?

A:1)首先必须将构造函数变为私有从而防止其他类实例化,并且只能有一个构造函数。因为系统会默认一个无参构造函数,而且默认public访问修饰符。 所以必须写一个私有无参让默认无效。(通常单例模式都是不带形参的)

   2)在该类中声明一个自己本身的静态实例,然后通过静态方法返回。

Q:如何提供一个全局访问点?

A:在类中创建一个公共并且静态的属性。(因为静态方法是类中的一个成员方法,属于整个类,即不用创建任何对象也可以直接调用。单例模式是不允许其他类实例的。)

代码:

分为两种模式:

1.LAZY模式

就是延迟加载, 设计模式是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据(读取属性值)的时候,才真正执行数据加载操作.有效使用它可以大大提高系统性能。

2.饿汉模式

与LAZY模式相反 ,加载时会将自己实例化。起来最容易的单例模式。

分析代码1:(经典)

// 不要用这种方式
public sealed class Singleton
{
  private static Singleton instance=null;//声明自己本身的静态实例
  private Singleton(){}//私有构造
  public static Singleton Instance() //提供全局访问点
  {
      if (instance==null)//实例不存在则创建
      {
        instance = new Singleton();
      }
      return instance;
  }
}

该代码仅供理解,单例模式的定义。

 问题:该方法是非线程安全的,当有两个线程同时进入时,如果instance为null则都会创建实例。实际上,在测试以前,实例就已经有可能被创建了,但是内存模型不能保证这个实例能被其他的线程看到。

下面我们优化改进

分析代码2:(非安全线程)

public sealed class Singleton
{
  private static Singleton instance = null;
  private static readonly object padlock = new object();//定义一个标识确保线程同步
  Singleton(){}
  public static Singleton Instance()
  {
      lock (padlock)//线程到达时加锁 运行完之后解锁 当遇到加锁线程就会挂起等待解锁
      {
        if (instance == null)
        {
          instance = new Singleton();
        }
        return instance;
      }
  }
}

以上解决了多线程问题。

问题:性能上来说,锁变成了每次都必须的当这个实例被响应的时候。此时完全没必要对线程辅助对象加锁之后再去判断,所以上面的实现方式增加了额外的开销。

下面我们进行优化改进:

 代码分析3:(双重锁定)

public sealed class Singleton
{
  private static Singleton instance = null;
  private static readonly object padlock = new object();
  Singleton(){}
  public static Singleton Instance
  {
    get
    {
      if (instance == null)//外层的if语句块,这使得每个线程欲获取实例时不必每次都得加锁,因为只有实例为空时(即需要创建一个实例),才需加锁创建
      {
        lock (padlock)
        {
          if (instance == null)
          {
            instance = new Singleton();
          }
        }
      }
      return instance;
    }
  }
}

这种“双重检查锁定”理论上是完美的

问题是:并不能保证它会在单处理器或多处理器计算机上顺利运行。(反正就是有问题吧 之后再研读一下 看看具体是怎么回事)

代码分析4:(不完全LAZY)

public sealed class Singleton
{
  private static readonly Singleton instance = new Singleton();

  // 显示的static 构造函数
  //静态构造函数抑制了beforefieldinit 特性(访问成员之前就执行静态函数)
  static Singleton(){}
  private Singleton(){}
  public static Singleton Instance
  {
    get
    {
      return instance;
    }
  }
}

不完全LAZY模式(通过抑制beforefildinit特性并不能起到太大的效果)

 代码分析5:(完全LAZY)

public sealed class Singleton
{
  private Singleton(){}
  public static Singleton Instance { get { return Nested.instance; }}   
//嵌套类
  private class Nested
  {
    //抑制beforefieldinit特性
    static Nested(){}
    internal static readonly Singleton instance = new Singleton();
  }
}

这里使用了嵌套类(嵌套类型是LAZY加载的,也就是说嵌套类型在使用他时才会初始化)

代码分析6:(Lazy<T>)

public sealed class Singleton
{
//使用.NET4 Lazy<T>
  private static readonly Lazy<Singleton> lazy =new Lazy<Singleton>(() => new Singleton());
  public static Singleton Instance { get { return lazy.Value; } }
  private Singleton() {}
}

Lazy<T> 对象初始化默认是线程安全的,在多线程环境下,第一个访问 Lazy<T> 对象的 Value 属性的线程将初始化 Lazy<T> 对象,以后访问的线程都将使用第一次初始化的数据。

以上全部是LAZY模式,现在了解下饿汉模式

代码分析7:

public sealed class Singleton
{
    private static readonly Singleton instance=new Singleton();//直接实例化
    private Singleton(){}
    public static Singleton Instance()
    {
        return instance;
    }
}

在这种模式下,无需自己解决线程安全性问题,CLR会给我们解决。由此可以看到这个类被加载时,会自动实例化这个类,而不用在第一次调用Instance()后才实例化出唯一的单例对象。

为了优化系统当然还是选择优化模式。LAZY模式最好的应该是使用Lazy<T>简短安全。

以上都是我在博客园对单例模式学习的总结。今后会补充一些具体的项目中的案例让和我一样的新手更容易吸收理解最终达到举一反三。这里重点参考了这里的文章,希望大家有指教的地方多多提点。感谢。


# C#  # 单例模式  # Singleton  # Pattern  # C#单例模式Singleton的实现详解  # C#设计模式之Singleton模式  # C#服务生命周期:Singleton、Scoped、Transient用法及说明  # 加载  # 加锁  # 都是  # 类中  # 并不能  # 不完全  # 提供一个  # 创建一个  # 多线程  # 解锁  # 就会  # 是个  # 我在  # 第一个  # 是有  # 最好的  # 有可能  # 和我  # 才会  # 两种 


相关文章: 如何通过万网虚拟主机快速搭建网站?  网站制作价目表怎么做,珍爱网婚介费用多少?  如何用低价快速搭建高质量网站?  如何在万网开始建站?分步指南解析  c# 在高并发下使用反射发射(Reflection.Emit)的性能  php8.4新语法match怎么用_php8.4match表达式替代switch【方法】  建站org新手必看:2024最新搭建流程与模板选择技巧  c# 服务器GC和工作站GC的区别和设置  零服务器AI建站解决方案:快速部署与云端平台低成本实践  专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?  深圳防火门网站制作公司,深圳中天明防火门怎么编码?  香港服务器如何优化才能显著提升网站加载速度?  清单制作人网站有哪些,近日“兴风作浪的姑奶奶”引起很多人的关注这是什么事情?  建站之星如何快速生成多端适配网站?  小米网站链接制作教程,请问miui新增网页链接调用服务有什么用啊?  网站制作多少钱一个,建一个论坛网站大约需要多少钱?  如何快速搭建高效WAP手机网站吸引移动用户?  天河区网站制作公司,广州天河区如何办理身份证?需要什么资料有预约的网站吗?  专业公司网站制作公司,用什么语言做企业网站比较好?  全景视频制作网站有哪些,全景图怎么做成网页?  定制建站流程步骤详解:一站式方案设计与开发指南  北京建设网站制作公司,北京古代建筑博物馆预约官网?  建站之星在线客服如何快速接入解答?  湖南网站制作公司,湖南上善若水科技有限公司做什么的?  山东云建站价格为何差异显著?  建站之星伪静态规则如何正确配置?  武汉网站制作费用多少,在武汉武昌,建面100平方左右的房子,想装暖气片,费用大概是多少啊?  制作电商网页,电商供应链怎么做?  如何在IIS中新建站点并解决端口绑定冲突?  上海制作企业网站有哪些,上海有哪些网站可以让企业免费发布招聘信息?  相册网站制作软件,图片上的网址怎么复制?  西安专业网站制作公司有哪些,陕西省建行官方网站?  如何做网站制作流程,*游戏网站怎么搭建?  昆明网站制作哪家好,昆明公租房申请网上登录入口?  ,网页ppt怎么弄成自己的ppt?  高防服务器租用指南:配置选择与快速部署攻略  正规网站制作公司有哪些,目前国内哪家网页网站制作设计公司比较专业靠谱?口碑好?  定制建站平台哪家好?企业官网搭建与快速建站方案推荐  如何快速搭建支持数据库操作的智能建站平台?  IOS倒计时设置UIButton标题title的抖动问题  焦点电影公司作品,电影焦点结局是什么?  测试制作网站有哪些,测试性取向的权威测试或者网站?  C#如何序列化对象为XML XmlSerializer用法  实例解析Array和String方法  logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?  高性能网站服务器部署指南:稳定运行与安全配置优化方案  外贸公司网站制作,外贸网站建设一般有哪些步骤?  建站主机空间推荐 高性价比配置与快速部署方案解析  Android使用GridView实现日历的简单功能  建站之星如何保障用户数据免受黑客入侵? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。