• C# 设计模式巩固


     前言

      设计模式的文章很多,所以此文章只是为了巩固一下自己的基础,说的不详细请见谅。

     介绍 - 单例模式

      官方定义:确保一个类只有一个实例,并提供一个全局访问点。

      通俗定义:就是一个类只有一个单个实例。(也没啥区别)

     实现

      如何保证一个类只有一个实例呢?

      1. 首先一个类是如何创建实例的? - 通过构造函数

      2. 如何保证只创建一个呢? - 构造函数只执行一次

      3. 如何保证构造函数只执行一次呢? - 访问外部类无权访问

      4. 如何让访问外部类无权访问? - 私有方法

      问题解决,上代码:

        /// <summary>
        /// 单例类
        /// </summary>
        public class Singleton
        {
            /// <summary>
            /// 私有构造函数
            /// </summary>
            private Singleton() { }
            /// <summary>
            /// 单例字段
            /// </summary>
            private static Singleton _instance; 
            /// <summary>
            /// 单例对象
            /// </summary>
            public static Singleton Instance
            {
                get
                {
                    if (_instance == null)
                        _instance = new Singleton();
                    return _instance;
                }
            }
    
            /// <summary>
            /// 输出
            /// </summary>
            public void WriteLine()
            {
                Console.WriteLine("哈希Code : " + this.GetHashCode());
            }
        }

    测试输出 HashCode :

      class Program
        {
            static void Main(string[] args)
            {
                Singleton.Instance.WriteLine();
                Singleton.Instance.WriteLine();
                Singleton.Instance.WriteLine();
                Console.Read();
            }
        }

    结果:

    这样就结束了吗? -(身为C#老鸟的我还要考虑下线程安全的问题,考虑并发的情况)

    我们需要构建一个并发的情形及多条线程同时创建对象,下面我就用简单粗暴的方法,需要对单例进行修改:

            /// <summary>
            /// 单例对象
            /// </summary>
            public static Singleton Instance
            {
                get
                {
                    if (_instance == null)
                    {
                        Thread.Sleep(1);
                        _instance = new Singleton();
                    }
                    return _instance;
                }
            } 

    调用测试:

    class Program
        {
            static void Main(string[] args)
            {
                //线程1
                Thread thread1 = new Thread(new ThreadStart(() =>
                {
                    Singleton.Instance.WriteLine();
                }));
                //线程2
                Thread thread2 = new Thread(new ThreadStart(() =>
                {
                    Singleton.Instance.WriteLine();
                }));
                //线程3
                Thread thread3 = new Thread(new ThreadStart(() =>
                {
                    Singleton.Instance.WriteLine();
                }));
                thread1.Start();
                thread2.Start();
                thread3.Start();
                Console.Read();
            }
        }

    输出结果:

    所以我们要对代码进行改进(加锁):

    /// <summary>
        /// 单例类
        /// </summary>
        public class Singleton
        {
            /// <summary>
            ////// </summary>
            private static object locker = new object();
            /// <summary>
            /// 私有构造函数
            /// </summary>
            private Singleton() { }
            /// <summary>
            /// 单例字段
            /// </summary>
            private static Singleton _instance;
            /// <summary>
            /// 单例对象
            /// </summary>
            public static Singleton Instance
            {
                get
                {
                    lock (locker)
                    {
                        if (_instance == null)
                        {
                            Thread.Sleep(1);
                            _instance = new Singleton();
                        }
                    }
                    return _instance;
                }
            }
    
            /// <summary>
            /// 输出
            /// </summary>
            public void WriteLine()
            {
                Console.WriteLine("哈希Code : " + this.GetHashCode());
            }
        }

    测试结果:

    解决!

    锁是个好东西但是要慎用,它是很耗资源的。所以还需要对代码进行改进,看代码我们知道只有 _instancenull 时才需要考虑并发加锁,所以我们再次改进:

        /// <summary>
        /// 单例类
        /// </summary>
        public class Singleton
        {
            /// <summary>
            ////// </summary>
            private static object locker = new object();
            /// <summary>
            /// 私有构造函数
            /// </summary>
            private Singleton() { }
            /// <summary>
            /// 单例字段
            /// </summary>
            private static Singleton _instance;
            /// <summary>
            /// 单例对象
            /// </summary>
            public static Singleton Instance
            {
                get
                {
                    if(_instance == null)
                    {
                        lock (locker)
                        {
                            if (_instance == null)
                            {
                                Thread.Sleep(1);
                                _instance = new Singleton();
                            }
                        }
                    }
                    return _instance;
                }
            }
    
            /// <summary>
            /// 输出
            /// </summary>
            public void WriteLine()
            {
                Console.WriteLine("哈希Code : " + this.GetHashCode());
            }
        }

    欢迎批评指正!转载请注明出处:http://www.cnblogs.com/xinwang/p/6294784.html 

  • 相关阅读:
    阿里云快速搭建Node.js开发环境
    初始化阿里云服务器
    docker上安装tomcat
    阿里云搭建支付宝小程序
    阿里云docker上安装redis
    WARN o.a.c.c.AprLifecycleListener [log,175] The Apache Tomcat Native library failed to load. The error reported was [no tcnative1 in java.library.path:
    阿里云快速搭建网站
    云服务器(CentOS系统)完全卸载mysql
    wumeismart编译运行和部署系统
    阿里云ssh关闭,保持jar程序运行
  • 原文地址:https://www.cnblogs.com/xinwang/p/6294784.html
Copyright © 2020-2023  润新知