单例模式属于设计模式中最简单的一个模式,在实际应用中也非常广泛,但可能是受到各类教程的影响,看到很多实现方式仍然沿用Java的那一套,其实在.NET中可以用更简洁的实现方式。

一、知识点介绍

核心目标:为了项目各处调用的都是同一个实例对象,从而实现资源共享。例如环境变量。

常见的实现方式:饿汉模式、懒汉模式、双锁模式、延迟加载模式

二、实现方式

/// <summary>
/// 饿汉模式,每次都加载会造成资源浪费
/// </summary>
public class EagerSingleton
{
public static Demo Instance { get; } = new Demo();
}
/// <summary>
/// 懒汉模式,适用于没有多线程的简单应用
/// </summary>
public class LazySingleton
{
private static Demo _instance = null;
public static Demo Instance
{
get
{
if (_instance == null)
_instance = new Demo();
return _instance;
}
}
}
/// <summary>
/// 线程安全
/// </summary>
public class ThreadSafeSingleton
{
private static Demo _instance = null;
private static readonly object _lock = new object();
public static Demo Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
_instance = new Demo();
}
}
return _instance;
}
}
}
/// <summary>
/// 延迟加载,利用静态类访问即创建的特点,兼顾易用性和线程安全的最佳实践
/// </summary>
public class DelaySingleton
{
/// <summary>
/// 内部静态类
/// </summary>
static class Nested
{
internal static readonly Demo Instance = new Demo();
} public static Demo Instance => Nested.Instance;
}

调用方式

static void Main(string[] args)
{
ThreadPool.SetMaxThreads(, );// 调整最大线程数
ThreadPool.SetMinThreads(, );// 调整最小线程数 Console.WriteLine("========== 示例:饿汉模式的多线程 ==========");
Parallel.For(, , (i) =>
{
Console.WriteLine($"{EagerSingleton.Instance.Id} ");
}); Console.WriteLine();
Console.WriteLine("========== 示例:懒汉模式的多线程 ==========");
Parallel.For(, , (i) =>
{
Console.WriteLine($"{LazySingleton.Instance.Id} ");
}); Console.WriteLine();
Console.WriteLine("========== 示例:线程安全模式的多线程 ==========");
Parallel.For(, , (i) =>
{
Console.WriteLine($"{ThreadSafeSingleton.Instance.Id} ");
}); Console.WriteLine();
Console.WriteLine("========== 示例:延迟加载模式的多线程 ==========");
Parallel.For(, , (i) =>
{
Console.WriteLine($"{DelaySingleton.Instance.Id} ");
}); Console.ReadKey();
} public class Demo
{
public string Id { get; private set; }
public Demo() { Id = Guid.NewGuid().ToString(); }
}

调用结果:

三、结论

饿汉模式适用于初学者,简单易记,但是没有考虑资源占用。

懒汉模式也适用于初学者,也简单易记,考虑了资源占用,但是没有考虑线程安全。

双锁模式兼顾了实用性和线程安全,实现比较繁琐,是以前比较常用的方式,比较直观好理解。

延迟加载模式,兼顾了易用性、简洁和线程安全,需要理解静态类的初始化机制,这种实现方式目前是最优解

> 单例模式不要实现 ICloneable 接口,不要涉及序列化,否则就会出现多个对象。

 四、参考资料

设计模式的征途—1.单例(Singleton)模式

C# 单例模式的五种写法

.NET单例模式快速学习应用的更多相关文章

  1. 60分钟Python快速学习(给发哥一个交代)

    60分钟Python快速学习 之前和同事谈到Python,每次下班后跑步都是在听他说,例如Python属于“胶水语言啦”,属于“解释型语言啦!”,是“面向对象的语言啦!”,另外没有数据类型,逻辑全靠空 ...

  2. LinqPad工具:帮你快速学习Linq

    LinqPad工具:帮你快速学习Linq 参考: http://www.cnblogs.com/li-peng/p/3441729.html ★:linqPad下载地址:http://www.linq ...

  3. 快速学习C语言一: Hello World

    估计不会写C语言的同学也都听过C语言,从头开始快速学一下吧,以后肯定能用的上. 如果使用过其它类C的语言,如JAVA,C#等,学C的语法应该挺快的. 先快速学习并练习一些基本的语言要素,基本类型,表达 ...

  4. 【Java线程池快速学习教程】

    1. Java线程池 线程池:顾名思义,用一个池子装载多个线程,使用池子去管理多个线程. 问题来源:应用大量通过new Thread()方法创建执行时间短的线程,较大的消耗系统资源并且系统的响应速度变 ...

  5. 【Java的JNI快速学习教程】

    1. JNI简介 JNI是Java Native Interface的英文缩写,意为Java本地接口. 问题来源:由于Java编写底层的应用较难实现,在一些实时性要求非常高的部分Java较难胜任(实时 ...

  6. 快速学习bootstrap前台框架

    W3c里的解释 使用bootstrap需要注意事项 1.  在html文件第一行要加上<!doctype html>[s1] 2.  导入bootstrap.min.css文件 3.  导 ...

  7. C#快速学习笔记(译)

    下面是通过代码快速学习C#的例子. 1.学习任何语言都必定会学到的hello,world! using System; public class HelloWorld { public static ...

  8. Dapper快速学习

    Dapper快速学习 我们都知道ORM全称叫做Object Relationship Mapper,也就是可以用object来map我们的db,而且市面上的orm框架有很多,其中有一个框架 叫做dap ...

  9. ASP.NET快速学习方案(.NET菜鸟的成长之路)

    想要快速学习ASP.NET网站开发的朋友可以按照下面这个学习安排进度走.可以让你快速入门asp.net网站开发!但也局限于一般的文章类网站!如果想学习更多的技术可以跟着我的博客更新走!我也是一名.NE ...

随机推荐

  1. Zookeeper未授权访问测试

    前言 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.它是一个为分布式应用提供一致性服务的软件,提 ...

  2. 代码审计准备之Thinkphp3

    0x01环境部署: 下载: 获取ThinkPHP的方式很多,官方网站(http://thinkphp.cn)是最好的下载和文档获取来源. 官网提供了稳定版本的下载:http://thinkphp.cn ...

  3. 线段树区间取max区间查询

    要线段树资瓷区间max和询问区间和. 设要把$[L, R]$对mx取max. 我们可以在线段树上二分出小于mx的区间然后变成区间修改了. 具体实现是,维护区间最小值和区间最大值,我们递归进入一个区间, ...

  4. Halcon一日一练:获取程序运行时间

    很多时候,我们需要知道每个函数的运算周期,以提高程序的运行效率.知道运行时间对于图像算法处理很重要 Halcon提供相关的算子,我们先来看代码: **获取图像处理时间 read_image(Image ...

  5. opencv::直方图计算

    直方图概念 上述直方图概念是基于图像像素值,其实对图像梯度.每个像素的角度.等一切图像的属性值,我们都可以建立直方图.        这个才是直方图的概念真正意义,不过是基于图像像素灰度直方图是最常见 ...

  6. FTPClient连续读取文件

    最近在使用FTPClient连续读取ftp上的多个文件内容时,遇到了两个问题: 1. 在for循环中,FTPClient只能读取到第一个文件内容,读取第二个时遇到NPE问题. 2. 遇到程序锁死. 下 ...

  7. python编程系列---多个装饰器装饰一个函数的执行流程

    首先看一个例子 ''' 多个装饰器装饰一个函数 ''' # 定义第一个装饰器 def set_func1(func): def wrapper1(*args,**kwargs): print('装饰内 ...

  8. Jedis运用scan删除正则匹配的key

    jedis运用scan删除正则匹配的key  我们都知道用keys *进行查询key的时候会进行堵塞,导致redis整体不可用,而使用scan命令则不会.   RedisServiceImpl中sca ...

  9. 详细解读 Spring AOP 面向切面编程(二)

    本文是<详细解读 Spring AOP 面向切面编程(一)>的续集. 在上篇中,我们从写死代码,到使用代理:从编程式 Spring AOP 到声明式 Spring AOP.一切都朝着简单实 ...

  10. 两种unity双击事件

    有时候需要用到双击事件,而unity未提供双击控件,在此提供两种双击事件方法,进攻参考: 1)此方法为通过unityevent来实现 首先新建image(或其他不带点击事件的控件),添加如下脚本,然后 ...