zoukankan      html  css  js  c++  java
  • 单例模式

    应用场景

    业务概念上只适合在系统中保留一份的数据,比如系统的配置信息类适合设计为单例模式,还可以使用单例模式解决多个实例访问资源冲突的问题。

    实现

    饿汉式

        public class Singleton
        {
            static readonly Singleton instance = new Singleton();
            private Singleton()
            {
    
            }
    
            public static Singleton GetInstance()
            {
                return instance;
            }
        }
    

    懒汉式

        public class Singleton
        {
            static Singleton instance = null;
            static readonly object lockObj = new object();
            private Singleton()
            {
    
            }
    
            public static Singleton GetInstance()
            {
                lock (lockObj)
                {
                    if (instance==null)
                    {
                        instance = new Singleton();
                    }
                }
                return instance;
            }
    
        }
    

    双重检测

        public class Singleton
        {
            static Singleton instance = null;
    
            static readonly object lockObj = new object();
            private Singleton()
            {
    
            }
    
            public static Singleton GetInstance()
            {
                if (instance==null)
                {
                    lock (lockObj)
                    {
                        if (instance==null)
                        {
                            instance = new Singleton();
                        }
                    }
                }
                return instance;
            }
    
        }
    

    简洁版双重检测,Lazy,Lazy是线程安全的,内部封装了需要的锁。

        public class Singleton
        {
            static Lazy<Singleton> singletonWrapper = null;
            private Singleton()
            {
    
            }
    
            public static Singleton GetInstance()
            {
                singletonWrapper = new Lazy<Singleton>(()=>new Singleton());
                return singletonWrapper.Value;
            }
        }
    

    内部静态类

        public class Singleton
        {
            private Singleton()
            {
    
            }
    
            private static class SingletonHolder
            {
                public static readonly Singleton instance = new Singleton();
            }
    
            public static Singleton GetInstance()
            {
                return SingletonHolder.instance;
            }
        }
    

    实现对比

    1. 饿汉式,在类加载期间就已经将instance静态类初始化好,所以instance实例的创建时线程安全的。不过饿汉式不支持延迟加载。

    2. 懒汉式,支持延迟加载,但是会导致频繁加锁、释放锁,以及并发度低的问题,频繁调用会产生性能瓶颈

    3. 双重检测,既支持延迟加载,又支持高并发。只要instance实例被创建之后,再调用GetInstance方法都不会进入到加锁的逻辑中。之所以会检查两次instance是否为null,是因为install为null,时,可能会有两个或者多个线程同时通过第一层检查,在一个线程创建完instance实例后,其他线程进入lock之内,不检查instance会再次创建实例。

    4. 内部静态类,既支持延迟加载,又支持高并发。延迟加载体现在外部单例类被加载时,并不会创建内部静态类,只有在调用GetInstance方法时,内部类才会被加载,这时才创建instance,内部静态类的实现比双重检测简单。

    单例模式存在的问题

    1. 违背了基于接口而非实现编程,在发生变化时,应用到单例类的代码都需要修改,也违背了开闭原则

    2. 单例会隐藏类之间的依赖关系,通过参数声明的以来关系,查看函数定义就能很容易识别出来,单例类不需要显式创建,不需要依赖参数传递,直接调用,如果代码比较复杂,这种调用关系会非常隐蔽

    3. 单例对代码的可测试性不友好

  • 相关阅读:
    WCF中关于可靠会话的BUG!!
    控制并发访问的三道屏障: WCF限流(Throttling)体系探秘[下篇]
    《天使之恋》,一部重口味的纯美爱情电影
    一个关于解决序列化问题的编程技巧
    [转]Design Rules for ModelViewPresenter
    你知道Unity IoC Container是如何创建对象的吗?
    只在UnitTest和WebHost中的出现的关于LogicalCallContext的严重问题
    使命必达: 深入剖析WCF的可靠会话[原理揭秘篇](上)
    回调与并发: 通过实例剖析WCF基于ConcurrencyMode.Reentrant模式下的并发控制机制
    如何编写没有Try/Catch的程序
  • 原文地址:https://www.cnblogs.com/Saints/p/12606962.html
Copyright © 2011-2022 走看看