zoukankan      html  css  js  c++  java
  • C#单例模式的实现再回顾

    一、单例模式的实现以及标准

    1、实例要是static类型,保证内存中只有一份copy

    2、不能够外部创建,也就是通过关键字private私有化构造函数

    3、提供一个外部访问方法GetInstance

    4、无论何时必须考虑线程安全问题

    二、懒汉模式

    需要时才创建,因此称作懒汉模式,代码示例如下:

        public class Robot
        {
            private static Robot m_instance = null;
            private static readonly object obj = new object();
    
            // close out init
            private Robot() { }
    
            public static Robot GetInstance()
            {
                if (m_instance == null)
                {
                    lock (obj)
                    {
                        if (m_instance == null)
                        {
                            m_instance = new Robot();
                        }
                    }
                }
    
                return m_instance;
            }
    
            public void SayHello()
            {
                System.Console.WriteLine("hello ,form singleton robot.");
            }
    
        }

    lock是为了保证线程安全,第一个if是判断是否需要创建,第二个是为了判断在多线程的情况下是否需要创建

    二、饿汉模式

    在声明的时候就创建,已经饿了,不管用不用,先创建,因此使用的时候效率会高一些,但一开始就占了内存,因此省时费空间

    private static readonly Robot m_instance = new Robot();

    // close out init
    private Robot() { }

    public static Robot GetInstance()
    {
    return m_instance;
    }

    public void SayHello()
    {
    System.Console.WriteLine("hello ,form singleton robot.");
    }

    }

    由于利用了静态变量的特性,因此一开始就创建完成,程序运行中又不会修改,因此线程安全。

    三、利用.net 4.0以后的lazy模板来实现懒汉模式,并且lazy模板自动线程安全

        public class Robot
        {
            private static readonly Robot m_instance = new Lazy<Robot>(()=>new Robot()).Value;
    
            // close out init
            private Robot() { }
    
            public static Robot GetInstance()
            {
                return m_instance;
            }
    
            public void SayHello()
            {
                System.Console.WriteLine("hello ,form singleton robot.");
            }
    
        }

    四、模板实现

    如果还觉得麻烦,那么好,可以试下一个模板

        public abstract class Singleton<T> where T : class//,new()
        {
            private static T singleton = null;
    
            private static readonly object obj = new object();
    
            protected Singleton(){}
            public static T GetInstance() 
            {
                if (singleton == null)
                {
                    lock (obj)
                    {
                        if (singleton == null)
                        {
                            singleton = (T)Activator.CreateInstance(typeof(T), true);
                        }
                    }
                }
    
                return singleton;
            }
        
        }
    
        public class Robot:Singleton<Robot>
        {
            private Robot() { }
            public void SayHello()
            {
                System.Console.WriteLine("hello ,form singleton robot.");
            }
    
        }

    注意:子类中需要关闭构造函数。

  • 相关阅读:
    每天一个linux命令(8):scp使用
    C++11 列表初始化
    国外程序员整理的C++资源大全
    fiddler4 使用教程
    C++11 右值引用和转移语义
    数据库炸了——是谁动了我的wait_timeout
    Go组件学习——gorm四步带你搞定DB增删改查
    Go组件学习——cron定时器
    Go语言学习——channel的死锁其实没那么复杂
    Go语言学习——彻底弄懂return和defer的微妙关系
  • 原文地址:https://www.cnblogs.com/xietianjiao/p/13524999.html
Copyright © 2011-2022 走看看