C#--设计模式之单例模式
单例模式大概是所有设计模式中最简单的一种,如果在面试时被问及熟悉哪些设计模式,你可能第一个答的就是单例模式。
单例模式的实现分为两种:
- 饿汉式:在静态构造函数执行时就立即实例化。
- 懒汉式:在程序执行过程中第一次需要时再实例化。
两者有各自适用的场景,实现方式也都很简单,唯一在设计时要考虑的一个问题就是:实例化时需要保证线程安全。
1. 饿汉式
饿汉式实现很简单,在静态构造函数中立即进行实例化:
public class Singleton
{private static readonly Singleton _instance;static Singleton(){_instance = new Singleton();}public static Singleton Instance{get{return _instance;}}
}
注意,为了确保单例性,需要使用 readonly 关键字声明实例不能被修改。
以上写法可简写为:
public class Singleton
{private static readonly Singleton _instance = new Singleton();public static Singleton Instance{get{return _instance;}}
}
这里的 new Singleton() 等同于在静态构造函数中实例化。在 C# 7 中还可以进一步简写如下:
public class Singleton
{public static Singleton Instance { get; } = new Singleton();
}
一句代码就搞定了,此写法,实例化也是在默认的静态构造函数中进行的。如果是饿汉式需求,这种实现是最简单的。有人会问这会不会有线程安全问题,如果多个线程同时调用 Singleton.Instance 会不会实例化了多个实例。不会,因为 CLR 确保了所有静态构造函数都是线程安全的。
注意,不能这么写:
public class Singleton
{public static Singleton Instance => new Singleton();
}
// 等同于:
public class Singleton
{public static Singleton Instance{get { return new Singleton(); }}
}
这样会导致每次调用都会创建一个新实例。
2. 懒汉式
懒汉式单例实现需要考虑线程安全问题,先来看一段经典的线程安全的单列模式实现代码:
public sealed class Singleton
{private static volatile Singleton _instance;private static readonly object _lockObject = new Object();public static Singleton Instance{get{if (_instance == null){lock (_lockObject){if (_instance == null){_instance = new Singleton();}}}return _instance;}}
}
网上搜索 C# 单例模式,大部分都是这种使用 lock 来确保线程安全的写法,这是经典标准的单例模式的写法,没问题,很放心。在 lock 里外都做一次 instance 空判断,双保险,足以保证线程安全和单例性。但这种写法似乎太麻烦了,而且容易写错。早在 C# 3.5 的时候,就有了更好的写法,使用 Lazy<T>。
示例代码:
public class LazySingleton
{private static readonly Lazy<LazySingleton> _instance =new Lazy<LazySingleton>(() => new LazySingleton());public static LazySingleton Instance{get { return _instance.Value; }}
}
调用示例:
public class Program
{public static void Main(){var instance = LazySingleton.Instance;}
}
使用 Lazy 可以使对象的实例化延迟到第一次被调用的时候执行,通过访问它的 Value 属性来创建并获取实例,并且读取一个 Lazy 实例的 Value 属性只会执行一次实例化代码,确保了线程安全。
3. 应用示例
static void Main(string[] args)
{LazySingleton p1 = LazySingleton.Instance();p1.GetName();LazySingleton p2 = LazySingleton.Instance();p2.GetName();if (p1 == p2){Console.WriteLine("他们是同一个人!");}else{Console.WriteLine("他们不是同一人!");}Console.ReadLine();
}public class LazySingleton
{private static volatile LazySingleton instance = null;//保证instance在所有线程中同步//private防止类在外部被实例化private LazySingleton(){ }public static LazySingleton Instance(){if (instance == null){instance = new LazySingleton();}return instance;}public void GetName(){Console.WriteLine("詹姆斯");}
}
程序运行结果:

相关文章:
C#--设计模式之单例模式
单例模式大概是所有设计模式中最简单的一种,如果在面试时被问及熟悉哪些设计模式,你可能第一个答的就是单例模式。 单例模式的实现分为两种: 饿汉式:在静态构造函数执行时就立即实例化。懒汉式:在程序执行过程中第一…...
RWEQ风蚀方程模型与ArcGIS数据处理Python代码库添加结合理论研究和科研实践
RWEQ模型是应用比较普遍的能适应大区域定量估算风蚀量的模型。该模型是基于大量野外实验的一种经验模型,在实际测定风力导致的土壤侵蚀量以及当地的气象、地表植被、土壤湿度、地表的结皮和地表的可蚀性等因子的基础上得出的一个经验方程。 1、掌握土壤风蚀模型的原…...
基于STM32微控制器的物联网(IoT)节点设计与实现
基于STM32微控制器的物联网(IoT)节点的设计和实现。我们讨论物联网节点的基本概念和功能,并详细介绍了STM32微控制器的特点和优势。然后,我们将探讨如何使用STM32开发环境和相关的硬件模块来设计和实现一个完整的物联网节点。最后,我们将提供一个示例代码,展示如何在STM3…...
篇二十一:中介者模式:解耦对象之间的交互
篇二十一:"中介者模式:解耦对象之间的交互" 开始本篇文章之前先推荐一个好用的学习工具,AIRIght,借助于AI助手工具,学习事半功倍。欢迎访问:http://airight.fun/。 另外有2本不错的关于设计模式…...
tomcat的多实例,动静分离(web服务基础结束)
多实例 多实例就是在一台服务器上有多个tomcat的服务(核心是改端口) 实验:多实例 安装步骤 1.安装好 jdk 2.安装 tomcat cd /opt tar zxvf apache-tomcat-9.0.16.tar.gz mkdir /usr/local/tomcat mv apache-tomcat-9.0.16 /usr/local/tomca…...
LeetCode150道面试经典题--判断子序列(简单)
1.题目 给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序…...
kubeadml 安装 k8s
目录 一:kubeadml 安装 k8s 1、网络环境 2、 环境准备 3、 所有节点安装docker 4、所有节点安装kubeadm,kubelet和kubectl 5、部署K8S集群 6、测试 二: 部署 Dashboard 一:kubeadml 安装 k8s 1、网络环境 master&am…...
考研C语言进阶题库——更新16-20题
目录 16计算t11/2...1/n-11/n 17计算1997! 18计算t1-122-133-...-1nn 19相传国际象棋是古印度舍罕王的宰相达依尔发明的.舍罕王十分喜爱象棋,决定让宰相自己选择何种赏赐. 这位聪明的宰相指着8*8共64格的象棋说:陛下,请您赏给我一些麦子吧. 就在棋盘的第1格放1粒…...
【变形金刚01】attention和transformer所有信息
图1.来源:Arseny Togulev在Unsplash上的照片 一、说明 这是一篇 长文 ,几乎讨论了人们需要了解的有关注意力机制的所有信息,包括自我注意、查询、键、值、多头注意力、屏蔽多头注意力和转换器,包括有关 BERT 和 GPT 的一些细节。因…...
面试热题(路径总和II)
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 在这里给大家提供两种方法进行思考,第一种方法是递归,第二种方式使用回溯的方式进行爆…...
测试 tensorflow 1.x 的一个demo 01
tensorflow 1.0的示例代码 demo_01.py import tensorflow as tf import os os.environ[TF_CPP_MIN_LOG_LEVEL]2def tf114_demo():a 3b 4c a bprint("a b in py ",c)a_t tf.constant(3)b_t tf.constant(4)c_t a_t b_tprint("TensorFlow add a_t b_t &…...
达蒙DM数据库使用经验
DM表/字段注释 注:dm数据库无法在建表的同时为字段名添加注释 //为表添加注释 comment on table 库名.表名 is 表注释; //为表字段添加注释 comment on column 库名.表名.列名 is 列注释;DM查询错误:无效的表或视图 1,确认表一定存在 2&am…...
Redis—集群
目录标题 主从复制第一次同步命令传播分担主服务器压力增量复制总结面试题什么是Redis主从复制Redis主从复制的原理Redis主从复制的优点Redis主从复制的缺点Redis主从复制的配置步骤Redis主从复制的同步策略主从节点是长还是短连接判断某个节点是否正常工作主从复制架构中&…...
【C语言】数据在内存中的存储详解
文章目录 一、什么是数据类型二、类型的基本归类三、 整型在内存中的存储1.原码、反码、补码2.大小端(1)什么是大小端(2)为什么会有大小端 四、浮点型在内存中的存储1. 浮点数存储规则 五、练习1.2.3.4.5.6.7. 一、什么是数据类型 我们可以把数据类型想象为一个矩形盒子&#x…...
PIC单片机配置字的设置
PIC单片机配置字的设置 PIC系列单片机,其芯片内部大都设置有一个特殊的程序存储单元,地址根据不同的单片机而定,此存储单元用来由单片机用户自由配置或定义单片机内部的一些功能电路单元的性能选项,所以被称之为系统配置字。目前PIC单片机系统配置字的方法有两种,一种是利…...
JavaWeb-Servlet服务连接器(一)
目录 1.Servlet生命周期 2.Servlet的配置 3.Servlet的常用方法 4.Servlet体系结构 5.HTTP请求报文 6.HTTP响应报文 1.Servlet生命周期 Servlet(Server Applet)是Java Servlet的简称。其主要的功能是交互式地浏览和修改数据,生成一些动态…...
新华三超融合态势感知标准版
产品概述: H3C SecCenter CSAP-XS 超融合态势感知一体机产品集合了态势感知和安全流量分析探针设备能无需复杂配置;态势感知平台具备强大的安全分析和可视化呈现功能;同时具备远程专家会诊功能,通过云端协同实现外部安全服务资源的…...
AutoSAR系列讲解(深入篇)13.2-Mcal Port配置
目录 一、配置界面 二、通用配置 1、ConfigVariant 2、PortSafety 3、PortGeneral 三、Port配置集合...
Java旋转数组中的最小数字(图文详解版)
目录 1.题目描述 2.题解 分析 具体实现 方法一(遍历): 方法二(排序): 方法三(二分查找): 1.题目描述 有一个长度为 n 的非降序数组,比如[1,2,3,4,5]&a…...
Android 13 Hotseat定制化修改——005 hotseat图标禁止形成文件夹
目录 一.背景 二.方案 一.背景 由于需求是需要自定义修改Hotseat,所以此篇文章是记录如何自定义修改hotseat的,应该可以覆盖大部分场景,修改点有修改hotseat布局方向,hotseat图标数量,hotseat图标大小,hotseat布局位置,hotseat图标禁止形成文件夹,hotseat图标禁止移动…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型
在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...
