• 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.");
            }
    
        }

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

  • 相关阅读:
    Unity赛车游戏之移动
    Unity3d5.0 新UI之2048
    关于Unity3d粒子系统的小发现(天堂3技能释放)
    偶然发现的Unity3d,两点之间的距离计算。
    JS函数声明的问题
    手写原生ajax
    xmlHttp.readyState的五种状态
    常见问题之数组去重
    Backbone中 View之间传值的解决办法
    JavaScript函数后面加不加括号的区别
  • 原文地址:https://www.cnblogs.com/xietianjiao/p/13524999.html
Copyright © 2020-2023  润新知