前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C# 单例模式

C# 单例模式

作者头像
Karl Du
发布2023-10-20 18:44:13
1580
发布2023-10-20 18:44:13
举报
文章被收录于专栏:Web开发之路Web开发之路

单例模式

单例模式(Singleton Pattern)是最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

注意:

  • 单例类只能有一个实例。
  • 单例类必须自己创建自己的唯一实例。
  • 单例类必须给所有其他对象提供这一实例。

意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。 主要解决:一个全局使用的类频繁地创建与销毁。 何时使用:当您想控制实例数目,节省系统资源的时候。 如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。 关键代码:构造函数是私有的。

实现:懒汉式,线程不安全

该实现没有额外开销,不要求线程安全的情况下可以使用:

代码语言:javascript
复制
public class ApplicationContext
{
    private static ApplicationContext instance = null;
    private ApplicationContext() { }

    public static ApplicationContext Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new ApplicationContext();
            }
            return instance;
        }
    }

    public string UserId { get; set; }
}

实现:懒汉式,线程安全

由于每次访问单例类实例都会加锁,而加锁是一个非常耗时的操作,故不推荐使用:

代码语言:javascript
复制
public class ApplicationContext
{
    private readonly static object lockObj = new object();
    private static ApplicationContext instance = null;
    private ApplicationContext() { }

    public static ApplicationContext Instance
    {
        get
        {
            lock (lockObj)
            {
                if (instance == null)
                {
                    instance = new ApplicationContext();
                }
            }
            return instance;
        }
    }

    public string UserId { get; set; }
}

实现:懒汉式,双重校验锁

在前面的基础上进行改进,只在第一次创建实例时加锁,提高访问性能:

代码语言:javascript
复制
public class ApplicationContext
{
    private readonly static object lockObj = new object();
    private static ApplicationContext instance = null;
    private ApplicationContext() { }

    public static ApplicationContext Instance
    {
        get
        {
            if (instance == null)
            {
                lock (lockObj)
                {
                    if (instance == null)
                    {
                        instance = new ApplicationContext();
                    }
                }
            }
            return instance;
        }
    }

    public string UserId { get; set; }
}

实现:饿汉式,线程安全

写法简单,线程安全,但构造时机不是由程序员掌控的:

代码语言:javascript
复制
public class ApplicationContext
{
    private static ApplicationContext instance = new ApplicationContext();
    private ApplicationContext() { }

    public static ApplicationContext Instance
    {
        get
        {
            return instance;
        }
    }

    public string UserId { get; set; }
}

不仅如此,假如ApplicationContext中存在其他静态方法,我去调用的时候就会导致单例构造实例,无法做到访问单例时创建实例

当然,通过内部类实现,可以解决这个问题:

代码语言:javascript
复制
public class ApplicationContext
{
    class Nested
    {
        internal static readonly ApplicationContext instance = new ApplicationContext();
    }

    private ApplicationContext() { }

    public static ApplicationContext Instance
    {
        get
        {
            return Nested.instance;
        }
    }

    public string UserId { get; set; }
}

实现单例基类

代码语言:javascript
复制
// 由于单例基类不能实例化,故设计为抽象类
public abstract class Singleton<T> where T : class
{
    // 这里采用实现5的方案,实际可采用上述任意一种方案
    class Nested
    {
        // 创建模板类实例,参数2设为true表示支持私有构造函数
        internal static readonly T instance = Activator.CreateInstance(typeof(T), true) as T;
    }
    private static T instance = null;
    public static T Instance { get { return Nested.instance; } }
}

参考资料

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021/01/21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 单例模式
  • 实现:懒汉式,线程不安全
  • 实现:懒汉式,线程安全
  • 实现:懒汉式,双重校验锁
  • 实现:饿汉式,线程安全
  • 实现单例基类
  • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档