• C#开发模式——单例模式


    一、单例模式简介

    单例模式是为保证一个对象,在程序运行的任何时刻只有一个实例存在,我们把这种实现方式称之为“单例模式”。

    二、单例模式的核心

    单例类只有一个实例存在

    单例类提供一个全局访问点

    单例类通过自己创建唯一实例

    单例类对外所有访问对象都提供一个唯一实例。

    三、单例模式的优点

    1、在程序运行中只有一个实例,减少内存占用,减少频繁的创建和销毁实例所带来的系统开销,

    2、避免资源的多种无效占用

    单例模式缺点:

    没有接口 不能继承

    四、单例模式应用场景

    当一个事物在特定的环境中,只会存在一个实例时,我们可以采用单例模式对其进行设计。

    例: 数据库连接池,计算机注册表 一个国家只有一个总统 日志系统中的日志文件 计算机中的打印池 计算机设备管理器

    生成唯一序列号 网站计数器

    五、单例模式的实现方式

    1、非线程安全(尽量不要用)

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

    说明:上面的方法是非线程安全的,2个不同的线程可以同时进入这个方法,如果instance为空的并且这里返回真的情况下,都可以创建实例,这显然违反了单例模式,实际上,在测试以前,实例就已经有可能被创建了,

    但是内存模型不能保证这个实例能被其他的线程看到,除非合适的内存屏障已经被跨过了。

    2、简单的线程安全

    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;
    
    }
    
    }
    
    }
    
    }

    上述实现是线程安全的。这个线程在共享的object上取出了一把锁,然后在创建实例以前检查这个实例是否被创建了。

    这个保护了内存屏障问题(lock保证了所有的读取操作是在LOCK获得以后发生的,所有的unlock保证了所有的写操作在lock 释放以后发生的),这样就保证了一个线程只能创建一个实例(每次只有一个线程在这段代码中运行),不巧的是,性能上来说,锁变成了每次都必须的当这个实例被响应的时候。

    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)
    
    {
    
    lock (padlock)
    
    {
    
    if (instance == null)
    
    {
    
    instance = new Singleton();
    
    }
    
    }
    
    }
    
    return instance;
    
    }
    
    }
    
    }

    4、不完全lazy,但是线程安全且不用用锁 推荐使用

    public sealed class Singleton
    
    {
    
    private static readonly Singleton instance = new Singleton();
    
    // 显示的static 构造函数
    
    //没必要标记类型 - 在field初始化以前
    
    static Singleton()
    
    {
    
    }
    
    private Singleton()
    
    {
    
    }
    
    public static Singleton Instance
    
    {
    
    get
    
    {
    
    return instance;
    
    }
    
    }
    
    }

    欢迎关注我的公众号(同步更新文章)DoNet技术分享平台

    阅读原文

  • 相关阅读:
    我把问烂了的⭐MySQL⭐面试题总结了一下(带答案,万字总结,精心打磨,建议收藏)
    在高并发情况下我是这样解决单用户超领优惠券问题
    js 数组去重十几种解法,基础知识扎实吗?(附数组方法)
    Jackson 解析 JSON 详细教程
    解锁各种js数组骚操作,总有你想要的!
    JS 异步编程的 5 种解决方案
    YARN 架构设计 和 RPC 网络通信
    基于消息队列构建实时大数据日志分析系统_没用
    Java:List转Map (用stream实现)
    Java时间格式:yyyymmdd转换为yyyy年mm月dd日
  • 原文地址:https://www.cnblogs.com/hgmyz/p/7239113.html
Copyright © 2020-2023  润新知