• 设计模式之单例模式


    单例模式的好处:

      单例模式的好处就是单例,就是全局唯一的一个实例,应对一些特殊情况,比如数据库连接池(内置了资源)全局唯一奥玛生成器,单例可以避免重复创建,但是也会常驻内存,除非真的有必要,否则不要用单例模式。

    单例模式:

      1、构造函数私有化,避免别人还去new

      2、公开的静态方法提供对象实例

      3、初始化一个静态字段用于返回,保证全局都是这一个。

    /// <summary>
    /// 单例类:一个构造对象很耗时耗资源类型
    /// 懒汉式单例模式
    /// </summary>
    public class Singleton
    {
        /// <summary>
        /// 构造函数耗时耗资源
        /// </summary>
        private Singleton()
        {
        }
        /// <summary>
        /// 3 全局唯一静态  重用这个变量
        /// </summary>
        private static volatile Singleton _Singleton = null;
        
        /// <summary>
        /// 2 公开的静态方法提供对象实例
        /// </summary>
        /// <returns></returns>
        public static Singleton CreateInstance()
        {
            _Singleton = new Singleton();
            return _Singleton;
        }
    }

    可以用以object.ReferenceEquals来验证创建的实例是不是同一个

     Singleton singleton1 = Singleton.CreateInstance();
     Singleton singleton2 = Singleton.CreateInstance();
     Singleton singleton3 = Singleton.CreateInstance();
     Console.WriteLine(object.ReferenceEquals(singleton1, singleton2));
     Console.WriteLine(object.ReferenceEquals(singleton3, singleton2));

    在多线程下,同事开启5个线程去创建呢?

     for (int i = 0; i < 5; i++)
     {
         Task.Run(() =>//启动线程完成--5个线程并发执行,同时去执行这个方法
         {
             Singleton singleton1 = Singleton.CreateInstance();
             singleton1.Show();
         });
     }

    这里就会出现多线程的问题,下面来解决多线程面临的问题。

    /// <summary>
    /// 单例类:一个构造对象很耗时耗资源类型
    /// 懒汉式单例模式
    /// </summary>
    public class Singleton
    {
        /// <summary>
        /// 构造函数耗时耗资源
        /// </summary>
        private Singleton()
        {
            long lResult = 0;
            for (int i = 0; i < 10000000; i++)
            {
                lResult += i;
            }
            Thread.Sleep(2000);
            Console.WriteLine("{0}被构造一次", this.GetType().Name);
        }
        /// <summary>
        /// 3 全局唯一静态  重用这个变量
        /// </summary>
        private static volatile Singleton _Singleton = null;
        //volatile 促进线程安全 让线程按顺序操作
        private static readonly object Singleton_Lock = new object();
        /// <summary>
        /// 2 公开的静态方法提供对象实例
        /// </summary>
        /// <returns></returns>
        public static Singleton CreateInstance()
        {
            if (_Singleton == null)//是_Singleton已经被初始化之后,就不要进入锁等待了
            {
                lock (Singleton_Lock)
                //保证任意时刻只有一个线程进入lock范围
                //也限制了并发,尤其是_Singleton已经被初始化之后
                {
                    //Thread.Sleep(1000);
                    //Console.WriteLine("等待锁1s之后才继续。。。");
                    if (_Singleton == null)//保证只实例化一次
                    {
                        _Singleton = new Singleton();
                    }
                }
            }
            return _Singleton;
        }
    
        //既然是单例,大家用的是同一个对象,用的是同一个方法,那还会并发吗  还有线程安全问题吗?
        public int iTotal = 0;
        public void Show()
        {
            //lock (Singleton_Lock)
            //{
                this.iTotal++;
            //}
        }
    
        public static void Test()
        {
            Console.WriteLine("Test1");
            Console.WriteLine(_Singleton.iTotal);
        }
    
    }
  • 相关阅读:
    golang实现dns域名解析(一)
    互联网协议入门(一)(转)
    DNS入门(转)
    随笔:Golang 时间Time
    mysql查询某一个字段是否包含中文字符
    screen状态变Attached连接会话失败
    golang :连接数据库闲置断线的问题
    神奇的GO语言:空接口(interface)
    Go语言:变参函数
    go语言:函数参数传递详解
  • 原文地址:https://www.cnblogs.com/taotaozhuanyong/p/11548867.html
Copyright © 2020-2023  润新知