首页 > 其他分享 >单例模式之延迟加载和初始加载

单例模式之延迟加载和初始加载

时间:2023-01-20 13:44:07浏览次数:47  
标签:Singleton Lazy 线程 单例 static 加载 延迟

一、什么是初始加载?

实现单例模式有两种方式,一种是懒加载,也就是延迟加载,当首次调用时创建单例对象,另一种是初始加载,在应用程序启动时就初始化单例对象,并将其保存在内存中以备将来使用,而不是需要时才创建。初始加载不需要考虑多线程环境导致的线程不安全问题,因为CLR将负责对象初始化和线程安全。这意味着我们不需要显式地编写任何代码来处理多线程环境的线程安全性。如下:

public sealed class Singleton
{
    private static int counter = 0;
    private static readonly Singleton singleInstance = new Singleton(); 
    private Singleton()
    {
        counter++;
        Console.WriteLine("Counter Value " + counter.ToString());
    }
    
    public static Singleton GetInstance
    {
        get
        {
            return singleInstance;
        }
    }
    public void PrintDetails(string message)
    {
        Console.WriteLine(message);
    }
}

定义私有静态常量singleInstance,并实例化Singleton对象赋值给该常量,由于是静态的,所以在应用启动就会创建,并加载到内存中,可以随时调用。主要由CLR在内部负责变量的初始化以及即时加载中的线程安全。

二、什么是延迟加载?

定义私有静态常量,但是并不实例化赋值,而是等到首次调用时再创建实例,往后每次调用就用这一个实例。也就是将对象的初始化延迟到需要它的时候。当创建对象的成本非常高以及很少使用该对象时,需要使用延迟加载。如果使用得当,延迟加载可以提高应用程序的性能。在C#中可以使用Lazy关键字使单例实例延迟加载。

三、理解C#中的Lazy关键字

Lazy是在.NET Framework 4.0引入的,提供对延迟初始化的支持。使用方式如下:

private static readonly Lazy<Singleton> Instancelock = new Lazy<Singleton>(() => new Singleton());

非常重要的一点是: Lazy<T> 对象在默认情况下是线程安全的。在多线程环境中,当多个线程试图同时访问相同的 GetInstance 属性时,Lazy将负责线程安全。代码如下:

public sealed class Singleton
{
    private static int counter = 0;
    private static readonly Lazy<Singleton> Instancelock 
        = new Lazy<Singleton>(() => new Singleton());

    private Singleton()
    {
        counter++;
        Console.WriteLine("Counter Value " + counter.ToString());
    }
    public static Singleton GetInstance
    {
        get
        {
            return Instancelock.Value;
        }
    }
    public void PrintDetails(string message)
    {
        Console.WriteLine(message);
    }
}

最后输出的结果和初始加载运行输出的结果是相同的,这是因为Lazy关键字只创建一个单例实例,而且它们在默认情况下是线程安全的。

标签:Singleton,Lazy,线程,单例,static,加载,延迟
From: https://www.cnblogs.com/dcy521/p/17062162.html

相关文章

  • 线程安全单例设计模式
    一、什么是单例设计模式中的线程安全?首先,创建一个单例类:publicsealedclassGuidService{privatestaticintcounter=0;privatestaticGuidService?_gu......
  • dremio DACModule 模块加载简单说明
    dremioDACModule主要是模块加载初始化以及组合,是一个比较重要的模式,同时也支持基于配置进行加载(有点很多了,后边简单介绍)加载机制支持配置加载可以通过dremio运行配......
  • 类加载器的理解——基于Launcher类
    文章目录​​一、理论入口​​​​二、创建加载器​​​​1、扩展类加载器(Ext)​​​​2、应用类加载器(App)​​​​3、补充​​​​三、双亲委派机制​​阅读本文你将收获:1、......
  • 使用Graalvm加载Shellcode
    Graalvm介绍介绍Graalvm之前,首先就要了解Java编译的JIT和AOT是什么JIT(Just-in-Time,即时编译)和AOT(Ahead-of-Time,预编译),就像Java常见的是需要什么类,就加载进来编译并......
  • 单例模式类为什么需要用sealed关键字修饰?
    使用单例设计模式,需要确保在任何给定的时间点对于整个应用程序只有一个特定类的实例可用。使用私有构造函数,可以避免类在外部被实例化,但是却无法避免内部类(嵌套类)的继承,如......
  • 生成此程序集的运行时比当前加载的运行时新,无法加载此程序集。
    生成此程序集的运行时比当前加载的运行时新,无法加载此程序集。https://www.cnblogs.com/king10086/p/13516149.html一、运行demo时 出现这个问题,是因为生产的程序与引......
  • pnpm : 无法加载文件 \AppData\Roaming\npm\pnpm.ps1,因为在此系统上禁止运行脚本
    1.安装pnpmnpminstall-gpnpm#安装pnpmpnpm--version#查看pnpm版本安装完成后查看版本时报错pnpm:无法加载文件C:\Users\123\AppData\Roaming\npm\pnpm.p......
  • RocketMQ的延迟消息
    什么是延迟消息延迟消息顾名思义不是用户能立即消费到的,而是等待一段特定的时间才能收到。举例如下场景比较适合使用延时消息:场景一:物联网系统经常会遇到向终端下发命令......
  • 基于Netty的HashedWheelTimer实现延迟任务
    packagecom.cmcc.open.ota.config;importio.netty.util.HashedWheelTimer;importio.netty.util.Timeout;importio.netty.util.TimerTask;importlombok.extern.s......
  • jvm:类加载子系统干什么的?由什么组成?需要记住哪些八股文?
    jvm:类加载子系统干什么的?由什么组成?需要记住哪些八股文?最近刚工作,有点懈怠了,看抖音的时候,发现大家都在学jvm,正好咕咕也在这方面一直有想要学习的东西,就参考了一下别人,学习了......