• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C# 单例模式

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

单例模式解读:

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

步骤:

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

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

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

第一种方法:

    /// <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!

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
CF1444C Team-Building发布时间:2022-07-14
下一篇:
一文让你明白C语言中的指针发布时间:2022-07-14
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap