定义
保证一个类仅有一个实例,并提供一个该实例的全局访问点。 --《设计模式GoF》
UML类图
使用场景
- 当类只能有一个实例并且用户可以从一个众所周知的访问点访问它时。
- 创建一个对象需要消耗过多的资源,比如IO和数据库连接等。
C#代码实现
1,初始版本
namespace DesignPatternDemo.ConsoleApp { /// <summary> /// 单例类 /// </summary> public class Singleton { private static Singleton _singleton; private Singleton() { } public static Singleton GetInstance() { if (_singleton== null) { _singleton = new Singleton(); } return _singleton; } } }
注意:此版本在多线程环境下不能保证线程安全!
2,双检锁
namespace DesignPatternDemo.ConsoleApp { /// <summary> /// 单例类(双检锁) /// </summary> public class SingletonV2 { private static SingletonV2 _singleton; private static readonly object lockObj = new object(); private SingletonV2() { } public static SingletonV2 GetInstance() { if (_singleton == null) { lock (lockObj) { if (_singleton == null) { _singleton = new SingletonV2(); } } } return _singleton; } } }
总结:双检锁版本解决了多线程环境下线程安全的问题。
3,饿汉式版本
namespace DesignPatternDemo.ConsoleApp { /// <summary> /// 单例类(饿汉式版本) /// </summary> public class SingletonV3 { private static readonly SingletonV3 _singleton = new SingletonV3(); private SingletonV3() { } public static SingletonV3 GetInstance() { return _singleton; } } }
总结:这个版本的优点是实现简单并且没有加锁执行效率高,缺点是类加载时就初始化,可能会浪费内存资源。
4,测试
namespace DesignPatternDemo.ConsoleApp { class Program { static void Main(string[] args) { SingletonV2 singleton1 = SingletonV2.GetInstance(); SingletonV2 singleton2 = SingletonV2.GetInstance(); if (singleton1 == singleton2) { Console.WriteLine("对象singleton1和对象singleton2是同一个对象!"); } Console.ReadKey(); } } }
运行结果:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架