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

    单例模式解读:

    在应用程序中,保证类型只有一个实例,只允许实例化一次;

    步骤:

    首先构造函数私有化,以保证对象不会被它人实例化;

    提供一个公开的静态方法供他人获取对象的实例;

    防止并发情况破坏单例,在创建对象时加锁

    第一种方法:

        /// <summary>
        /// 懒汉式单例写法:只有在调用CreateInstance方法后才会实例化Single对象
        /// </summary>
        public sealed class Single
        {
            private Single()
            {
                long result = 0;
                for (int i = 0; i < 10000; i++)
                {
                    result += i;
                }
                Thread.Sleep(1000);
                Console.WriteLine($"{this.GetType().Name}已被构造");
            }
            private static Single single = null;//静态字段在内存中是唯一的,不会被GC
            private static readonly object SingLock = new object();
    
            public static Single CreateInstance()
            {
                //先判断对象是否为null,不为null就不执行里面的代码,直接返回对象
                if (single == null)
                {
                    //加锁:任意时刻只有一个线程能进去,解决并发问题
                    lock (SingLock)
                    {
                        if (single == null)//这个判断不能去掉,保证只初始化一次
                        {
                            //方法第一次进来会new一个实例,只会被构造一次
                            single = new Single();
                        }
                    }
                }
                return single;
            }
            public void Message()
            {
                Console.WriteLine($"{typeof(Single)}");
            }
        }
    static void Main(string[] args)
            {
                for (int i = 0; i < 10; i++)
                {
                    Task.Run(() =>//会抛十个线程
                    {
                        Single single = Single.CreateInstance();
                        single.Message();
                    });
                }
                Console.WriteLine("Hello World!");
                Console.ReadKey();
            }

    第二种:

        /// <summary>
        /// 饿汉式单例写法:在调用类中的任意成员时都会先实例化这个类
        /// </summary>
        public class SingleSecond
        {
            private SingleSecond()
            {
                long result = 0;
                for (int i = 0; i < 10000; i++)
                {
                    result += i;
                }
                Thread.Sleep(1000);
                Console.WriteLine($"{this.GetType().Name}以被构造");
            }
            private static SingleSecond single = null;//静态字段在内存中是唯一的,不会被GC
    
            /// <summary>
            /// 静态构造函数:由CLR保证,在第一次使用到这个类型之前,自动调用且只调用一次
            /// </summary>
            static SingleSecond()
            {
                single = new SingleSecond();
            }
            public static SingleSecond CreateInstance()
            {
                return single;
            }
            public void Message()
            {
                Console.WriteLine($"{typeof(SingleSecond)}");
            }
        }
    static void Main(string[] args)
            {
                for (int i = 0; i < 10; i++)
                {
                    Task.Run(() =>//会抛十个线程
                    {
                        SingleSecond single = SingleSecond.CreateInstance();
                        single.Message();
                    });
                }
                Console.WriteLine("Hello World!");
                Console.ReadKey();
            }

    第三种:

        /// <summary>
        /// 饿汉式单例写法:在调用类中的任意成员时都会先实例化这个类
        /// </summary>
        public class SingeThird
        {
            private SingeThird()
            {
                long result = 0;
                for (int i = 0; i < 10000; i++)
                {
                    result += i;
                }
                Thread.Sleep(1000);
                Console.WriteLine($"{this.GetType().Name}以被构造");
            }
            /// <summary>
            /// 静态字段:由CLR保障,在第一次使用这个类型之前,会自动初始化且初始化一次
            /// </summary>
            private static SingeThird single = new SingeThird();
            public static SingeThird CreateInstance()
            {
                return single;
            }
            public void Message()
            {
                Console.WriteLine($"{typeof(SingleSecond)}");
            }
        }
     static void Main(string[] args)
            {
                for (int i = 0; i < 10; i++)
                {
                    Task.Run(() =>//会抛十个线程
                    {
                        SingeThird single = SingeThird.CreateInstance();
                        single.Message();
                    });
                }
                Console.WriteLine("Hello World!");
                Console.ReadKey();
            }

    单例模式的特点:

    同一个实例不能解决多线程并发问题,会存在线程冲突;

    全局只有一个单例,对对象里的成员进行修改时,在任何地方调用都是上次修改的值,而不是初始值;

    The End!

  • 相关阅读:
    Gvim快捷键学习
    一步一步学习Vim 全图解释
    经典vim插件功能说明、安装方法和使用方法介绍
    中国数学数字图书馆
    RQNOJ第一题---PID1 / 明明的随机数
    gdb常用命令
    linux c下mysql编程样例
    linux c编程 -- 线程互斥
    linux c多线程编程范例
    数据结构 -- 可重用模块的接口设计模板
  • 原文地址:https://www.cnblogs.com/zhangnever/p/12402194.html
Copyright © 2011-2022 走看看