随笔 - 410  文章 - 0  评论 - 519  阅读 - 148万 

定义

保证一个类仅有一个实例,并提供一个该实例的全局访问点。  --《设计模式GoF》

UML类图

image

使用场景

  1. 当类只能有一个实例并且用户可以从一个众所周知的访问点访问它时。
  2. 创建一个对象需要消耗过多的资源,比如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();
        }
    }
}
复制代码

运行结果:

image

posted on   永远的麦子  阅读(961)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示