C# 语句中的各种单例模式代码

1、非线程安全(经典模式),但没有考虑线程安全,在多线程时可能会出问题,不过还从没看过出错的现象。

/// <summary>
    /// 单例模式的实现
    /// </summary>
    public class Singleton
    {
        // 定义一个静态变量来保存类的实例
        private static Singleton uniqueInstance;

        // 定义私有构造函数,使外界不能创建该类实例
        private Singleton()
        {
        }

        /// <summary>
        /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
        /// </summary>
        /// <returns></returns>
        public static Singleton GetInstance()
        {
            // 如果类的实例不存在则创建,否则直接返回
            if (uniqueInstance == null)
            {
                uniqueInstance = new Singleton();
            }
            return uniqueInstance;
        }
    }

2、简单安全线程

/// <summary>
    /// 单例模式的实现
    /// </summary>
    public class Singleton
    {
        // 定义一个静态变量来保存类的实例
        private static Singleton uniqueInstance;

        // 定义一个标识确保线程同步
        private static readonly object locker = new object();

        // 定义私有构造函数,使外界不能创建该类实例
        private Singleton()
        {
        }

        /// <summary>
        /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
        /// </summary>
        /// <returns></returns>
        public static Singleton GetInstance()
        {
            // 当第一个线程运行到这里时,此时会对locker对象 "加锁",
            // 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁
            // lock语句运行完之后(即线程运行完之后)会对该对象"解锁"
            lock (locker)
            {
                // 如果类的实例不存在则创建,否则直接返回
                if (uniqueInstance == null)
                {
                    uniqueInstance = new Singleton();
                }
            }

            return uniqueInstance;
        }
    }

上面这种解决方案确实可以解决多线程的问题,但是上面代码对于每个线程都会对线程辅助对象locker加锁之后再判断实例是否存在,对于这个操作完全没有必要的,因为当第一个线程创建了该类的实例之后,后面的线程此时只需要直接判断(uniqueInstance==null)为假,此时完全没必要对线程辅助对象加锁之后再去判断,所以上面的实现方式增加了额外的开销,损失了性能,为了改进上面实现方式的缺陷,我们只需要在lock语句前面加一句(uniqueInstance==null)的判断就可以避免锁所增加的额外开销,这种实现方式我们就叫它 “双重锁定”,下面是具体实现代码:

3、尝试线程安全(双重锁定)

  /// <summary>
    /// 单例模式的实现
    /// </summary>
    public class Singleton
    {
        // 定义一个静态变量来保存类的实例
        private static Singleton uniqueInstance;

        // 定义一个标识确保线程同步
        private static readonly object locker = new object();

        // 定义私有构造函数,使外界不能创建该类实例
        private Singleton()
        {
        }

        /// <summary>
        /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
        /// </summary>
        /// <returns></returns>
        public static Singleton GetInstance()
        {
            // 当第一个线程运行到这里时,此时会对locker对象 "加锁",
            // 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁
            // lock语句运行完之后(即线程运行完之后)会对该对象"解锁"
            // 双重锁定只需要一句判断就可以了
            if (uniqueInstance == null)
            {
                lock (locker)
                {
                    // 如果类的实例不存在则创建,否则直接返回
                    if (uniqueInstance == null)
                    {
                        uniqueInstance = new Singleton();
                    }
                }
            }
            return uniqueInstance;
        }
    }

4、饿汉模式(这种模式的特点是自己主动实例。)

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

        public static Singleton GetInstance()
        {
               return instance;
        }
}

5、不完全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;
        }
    }
}

6、完全延迟实例化

public sealed class Singleton
{
    private Singleton()
    {
    }

    public static Singleton Instance { get { return Nested.instance; } }
        
    private class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        {
        }

        internal static readonly Singleton instance = new Singleton();
    }
}

7、使用 .NET 4's Lazy<T> 类型

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

    private Singleton()
    {
    }
}

 

详细内容介绍见网址:http://csharpindepth.com/Articles/General/Singleton.aspx#unsafe

 

转载于:https://www.cnblogs.com/Study088/p/7762745.html

【超详细】C#的单例模式 本文详细介绍了C#中的单例设计模式,包括两种实现方式:普通类泛型单例(Singleton<T>)和基于MonoBehaviour的组件单例(MonoSingleton<T>)。单例模式通过私有构造、静态私有实例和公共访问入口确保全局唯一实例,具有节省资源、保证数据一致性等优势。文章分别阐述了两者的核心原理、代码实现、使用场景及注意事项,并提供了日志管理器和音效管理器的具体应用示例。特别强调了多线程安全、初始化时机和避免过度使用等重要原则,为Unity开发中合理运用单例模式提供了全面指导。 阅读详情

相关推荐

C#设计模式--单例模式

普通单例:一进门就把所有家具都准备好(程序启动时就创建实例)懒加载单例:等你要用沙发时才去买沙发(第一次访问时才创建实例)

weixin_53545579的博客 1274

C#中的单例模式

单例模式是一种确保一个类只有一个实例的设计模式。比如在各种工具类中,每次需要访问这个类的方法时,都实例化一个实例,这是明显不合适的通过上述实现单例模式的各种方法的探讨,我们还需要在实际开发过程中,根据不同的需求来进行选择不同的实现方式。比如一个比较小的项目,后续改动不大,可以通过第一种来实现;比如我们开发ASP.Net,这时我们就需要用到这种方式。

qq_29965505的博客 5270

C#实现单例模式(附完整源码)

C#实现单例模式(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 411

C#中的五种单例模式(SIngleton)

1. 写法一(只适用于单线程环境) public sealed class Singleton1 { private Singleton1(){} private static Singleton1 instance = null; public static Singleton1 Instance { get { if(instance == null) ...

q526261747的博客 4617

c# 单例模式的实现方法

主要介绍了c# 单例模式的实现方法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下

vietjetair 航空的webpack多参数生成学习

工作内不是特别多,居安思危,有一个抓机票信息的公司面试前竟然需要做面试题,这就是一个题。看了下,有点麻烦,webpack 最初不得要领,看了下资料,找了个框架,练了两个简单的,搞这个吧。入库需要自己找,有几个参数不是明文的,算法不是很复杂,位置不太好找。整体难度一般。

liu_yueyang的博客 1510

C# 单例模式的六种实现

很久没有在优快云上写笔记了,这次写一下比较常见的单例模式。 单例模式的所有实现的第一条就是必须将类的构造函数设置为私有,使得其他类没有变法直接调用构造函数生产对象。先看最简单的一种: 1.单线程单例模式 public sealed class Singleton { public static Singleton instance = null; private Si...

q__y__L的博客 8728

通达信量化打板选股指标公式源码副图

X_2:=3*LOW;X_13:=4;X_14:=3;X_15:=2;X_16:=1;

gpzb7的博客 4484

c#-单例模式

单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点来获取该实例。以下是详细介绍单例模式的各种实现方式。

ly1h1的博客 3263

ThinkPad T14 Gen 2与T14P系列对比

表格您的需求推荐机型日常办公、出差、文档处理、视频会议✅(够用、轻便、便宜)视频剪辑、3D建模、编程编译、AI训练、高色准设计✅(性能强、屏幕好、扩展佳)想要未来 5 年不换机✅T14p预算低于 5000 元✅T14 Gen 2(或考虑 T14 Gen 3/4)T14p 2025 款 ≠ 小改款,而是架构级升级它从“高性能笔记本”进化为“AI 移动工作站”,核心差异在于NPU + Ultra 平台 + 全面屏显 + 超长续航。如果您从事AI 开发、视频创作、工程仿真、多任务编程。

tecoes的博客 2746

别再瞎调了!手把手教你用ADI IIO Oscilloscope配置AD936x的AGC(附Pluto SDR实测)

本文详细介绍了如何使用ADI IIO Oscilloscope工具配置AD936x系列射频捷变收发器的自动增益控制(AGC)功能,包括Slow/Fast Attack模式的参数设置与优化技巧。通过Pluto SDR硬件实测演示,帮助开发者快速掌握AGC配置方法,提升无线通信系统的接收性能。

weixin_30267785的博客 578

[设计模式]C# 单例模式

之前面试的时候被要求手写单例模式,还要对各种适用场景进行区分使用,虽然看了书,但是没做过总结,这次就记录下来吧。 单例模式 单例模式:保证一个类只有一个实例被创建,并且提供一个全局访问点。 代码实现 (1) public sealed class Singleton { private static Singleton instance = null; ...

隔壁老王三金的博客 364

Camera(5)metadata

Metadata 是整个 Android camera 中类似于高楼大厦中的管道系统一样,贯穿了整个 Camera 的 Framework 和 vendor HAL。Metadata 里面包含了所有的控制、参数、返回值等等。Metadata分为Android原生的Metadata和芯片商或者用户自定义的Metadata,即Android Tag和Vendor Tag。Vendor Tag在Hal中定义,并在camx和chi目录中使用。

qq_55893245的博客 3054

c#lock语句及在单例模式中应用

C#中的lock语句是怎么回事,有什么作用? C#中的lock语句将lock中的语句块视为临界区,让多线程访问临界区代码时,必须顺序访问。他的作用是在多线程环境下,确保临界区中的对象只被一个线程操作,防止出现对象被多次改变情况。 注意的地方有:lock对象必须是一个不可变对象,否则无法阻止另一个线程进入临界区。最好是private static readonly 或者private stati

akjw008的专栏 1377

5.2 自抗扰控制 (ADRC)

自抗扰控制(Active Disturbance Rejection Control, ADRC)是由韩京清研究员于1998年提出的一种不依赖被控对象精确数学模型的新型控制技术[reference:0]。其核心思想是将系统的模型不确定性、内部参数摄动以及外部负载变化等所有影响统一定义为“总扰动”,通过一个名为扩张状态观测器(ESO)的环节对其进行实时估计并主动补偿,从而实现动态解耦和强鲁棒性。

技术工作者 1176

车牌识别系统

随这图形图像技术的发展,现在的车牌识别技术准确率越来越高,识别速度越来越快。无论何种形式的车牌识别系统,它们都是由触发、图像采集、图像识别模块、辅助光源和通信模块组成的。车牌识别系统涉及光学、电器、电子控制、数字图像处理、计算视觉、人工智能等多项技术。触发模块负责在车辆到达合适位置时,给出触发信号,控制抓拍。辅助光源提供辅助照明,保证系统在不同的光照条件下都能拍摄到高质量的图像。图像预处理程序对抓拍的图像进行处理,去除噪声,并进行参数调整。然后通过车牌定位、字符识别,最后将识别结果输出。 牌照自动识别是一

FPGA/MATLAB学习教程/源码/项目合作开发 2万+

C#实现单例,保证线程安全

C#中的lock语句是怎么回事,有什么作用? C#中的lock语句将lock中的语句块视为临界区,让多线程访问临界区代码时,必须顺序访问。他的作用是在多线程环境下,确保临界区中的对象只被一个线程操作,防止出现对象被多次改变情况。 注意的地方有:lock对象必须是一个不可变对象,否则无法阻止另一个线程进入临界区。最好是private static readonly 或者pr...

H20838883的博客 335

【R语言】基于Biomod2集成平台探究物种分布区的构建流程(SDMs)

我为什么想要写这个内容呢?其实我已经想了很久了,但是一直没有把所有的代码给理清楚,此外这将是我之后研究的主要方向。本博客讲述了如何基于Biomod2集成平台构建物种分布模型的全流程,以及我在使用该模型时的一些心得,同时还有我提供的一些小福利(一键处理代码),可以十分快捷的帮助你完成SDMs的构建,写出你的中英文论文。

amyniez的博客,欢迎交流讨论 3890

【C#】lock语句及在单例模式中应用

C#中的lock语句是怎么回事,有什么作用? C#中的lock语句将lock中的语句块视为临界区,让多线程访问临界区代码时,必须顺序访问。他的作用是在多线程环境下,确保临界区中的对象只被一个线程操作,防止出现对象被多次改变情况。 注意的地方有:lock对象必须是一个不可变对象,否则无法阻止另一个线程进入临界区。最好是private static readonly 或者private stati

Teng's world 1172

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

【C#基础】C# 常用语句讲解

编程语言 C# 常用语句的讲解。

好学若饥,谦卑若愚。 4016

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C#中的主要流程控制语句之跳转语句

跳转语句用于改变程序的执行流程,转移到指定之处。 C#中有4中跳转语句:如下图所示: 1.Break语句 可以使用Break语句终止当前的循环或者它所在的条件语句。然后,控制被传递到循环或条件语句的嵌入语句后面的代码行。Break语句的语法极为简单,它没有括号和参数,只要将以下语句放到你希望跳出循环或条件语句的地方即可:  break; Break语句例子

邢金聪 廊坊师范学院九期信息技术提高班 5767

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

C# 和Unity 中的单例模式 详解

单例模式是C#中最常用的设计模式之一,但也是最容易被误用的模式。线程安全:确保多线程环境下也能保持单例延迟初始化:根据需求选择合适的初始化时机防御性编程:防止反射、序列化等方式破坏单例现代替代方案:优先考虑依赖注入容器管理单例需要严格控制实例数量全局访问点确实必要对象创建成本高且频繁使用只是为了方便访问而使用需要多态行为需要频繁测试的组件单例模式是一种强大的工具,但强大的工具需要负责任地使用。

qq_38358224的博客 865

C#中的switch语句详解

首先,我们需要一个表达式,它的值将被用于与case语句中的值进行比较。根据表达式的值,程序将跳转到与匹配的case值相对应的代码块中执行相应的代码。首先,我们需要一个表达式,它的值将被用于与case语句中的值进行比较。根据表达式的值,程序将跳转到与匹配的case值相对应的代码块中执行相应的代码。它允许程序根据一个表达式的值,选择执行与该值相关联的特定代码块。它允许程序根据一个表达式的值,选择执行与该值相关联的特定代码块。的值为6或7,将执行另一个共享的代码块,输出"Weekend"。

PodProgram的博客 1万+

C#-设计模式-单例模式

1、提供了对唯一实例的受控访问。2、由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能。3、允许可变数目的实例。

Asincereman的专栏 1538
上一篇: unity中实现监听鼠标的进入和退出某一个UI按钮
下一篇: unity中将多个图片进行椭圆排序
bake2003
博客等级 码龄10年 4粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值