• 面试官最爱问的设计模式-单例模式


    设计模式相关文章

    为什么单例模式一直是面试官的最爱,归根结底是单例模式既简单又不简单,简单的是写个单例模式确实很简单,但是单例模式引伸出的问题可以很多很多,比如多线程、延迟加载、静态构造函数、内部类等等。

    如果面试者能写出内部类实现的单例模式几乎很少,为什么要写内部类实现的单例模式,看了下面简单的介绍你就全部明白了。

    1、基本概念

    单例模式(Singleton)保证一个类仅有一个实例,并提供一个访问它的全局访问点。

    单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的抽象,而单例模式只有自己一个对象,也因此有些设计大师并把把其称为设计模式之一。

    2、常用几种形式

    A、最基本的

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

    单例模式 ,保证一个类只有一个示例
    类的自身保存唯一的实例,这个类可以保证没有其他实例被创建,并且可以提供一个访问实例的方法

    B、多线程模式

        public class Singleton
        {
            private static Singleton intance;
            private Singleton()
            {
            }
            private static readonly object thisLock = new object();
    
            public static Singleton GetInstance()
            {
                lock (thisLock)
                {
                    return intance ?? (new Singleton());
                }
            }
        }

    保证多线程环境下只有一个实例。

    C、双重锁定

    public class Singleton
        {
            //定义一个私有的静态全局变量来保存该类的唯一实例
            private static Singleton intance;
    
            //定义一个只读静态对象,且是在程序运行时创建的
            private static readonly object thisLock = new object();
    
            /// <summary>
            /// 构造函数必须是私有的
            /// 这样在外部便无法使用 new 来创建该类的实例
            /// </summary>
            private Singleton()
            {
            }
    
            /// <summary>
            /// 定义一个全局访问点
            /// 设置为静态方法
            /// 则在类的外部便无需实例化就可以调用该方法
            /// </summary>
            /// <returns></returns>
            public static Singleton GetInstance()
            {
                //这里可以保证只实例化一次
                //即在第一次调用时实例化
                //以后调用便不会再实例化
    
                //一重锁定 intance == null
                if (intance == null)
                {
                    lock (thisLock)
                    {
                        //二重锁定 intance == null
                        //return intance ?? (new Singleton());
                        if (intance == null)
                        {
                            intance = new Singleton();
                        }
                    }
                }
                return intance;
            }
        }

    双重锁定不让线程每次都加锁,而是在实例未被创建的时候再加锁处理

    以上ABC都是第一次引用时才将自己实例化 也称为懒汉式单例类

    D、静态初始化

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

    D这种自己被加载时就将自己实例化称为饿汉式单例类 (多线程下是安全的)

    E、登记式模式(holder内部类)

    public class Singleton
        {
            //构造方法是私有的,从而避免外界利用构造方法直接创建任意多实例。
            private Singleton()
            {
            }
    
            public static Singleton GetInstance()
            {
                return Holder.Intance;
            }
    
    
            //类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例
            //没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载
            private static class Holder
            {
                //静态初始化器由JVM来保证线程安全
                internal static readonly Singleton Intance = new Singleton();
            }
        }

    内部类只有在外部类被调用才加载,产生实例;不用加锁。

    此模式有上述两个模式的优点,屏蔽了它们的缺点,是最好的单例模式。

    3、优缺点

    懒汉式单例类

    优点:第一次调用才初始化,避免内存浪费

    缺点:必须加锁才能保证单例,但加锁会影响效率

    饿汉式单例类(静态初始化)

    优点:没有加锁,执行效率会提高

    缺点:类加载就实例化对象。提前占用系统资源

    建议用内部类实现单例模式

    4、单例模式使用场景

    A、资源共享的情况下,避免由于资源操作时导致的性能或损耗,如日志文件,配置文件

    B、控制资源的情况下,方便资源之间的互相通信。如线程池

  • 相关阅读:
    [语录]学习和知识建立于见解的多样性上
    [语录]要紧的是选择能干、诚实而且勤勉的人
    [EnterpriseServices]利用assembly定义我们的组件在COM+中的注册方式
    [EntLib]在SR.Strings中使用中文字符串资源
    如何让Win2000和XP SP1支持System.EnterpriseServices(XP已验证)
    [C#]使用HttpWebRequest请求远端服务器时如何加载SSL证书
    [纪事]再见,CodeArtist(下)
    [ZT]Google Web Accelerator 进一步的发展?
    [纪事]再见,CodeArtist
    [WiX]我的第一个WiX安装脚本
  • 原文地址:https://www.cnblogs.com/yinrq/p/5275211.html
Copyright © 2020-2023  润新知