环球ug官网:C#‘中的’Singleton{模式}

admin 4个月前 (06-05) 科技 36 0

目录
  • 前言
  • “‘实现思绪’”
  • 「实现方式」[
    • 最简朴的 「实现方式」[
    • (若是多线)程乱入?
    • <线程>平安的单例【模式】
      • Lock【‘‘版本’’】
      • 静态组织器【‘‘版本’’】
      • Lazy【‘‘版本’’】
  • “总结”

前言

Singleton是二十三个设计【模式】中对照主要也对照经常使用的【模式】。(〖然则〗这个【模式】虽然简朴),『实现起来也会有一些小坑』,【让我们一起来看看吧】!

“‘实现思绪’”

首先我们看看这个设计【模式】的UML类图。

很清晰的可以看到,<有三点是需要我们在实现这个【模式】〖的时刻〗注重的地方>。

  • <私有化的组织器>
  • (全局唯)一的静态实例
  • 能够返回全局唯一静态实例的静态方式

其中,私有化组织器是防止外部用户建立新的实例而静态方式用于返回(全局唯)一的静态实例供用户使用。原理清晰了,接下来我们看看一些典型的 「实现方式」[和其中的暗坑。

「实现方式」[

最简朴的 「实现方式」[

最简朴的 「实现方式」[自然就是根据UML(类图直接写一)个类,我们看看代码。

    class Program
    {
        static void Main(string[] args)
        {
        	var single1 = Singleton.Instance;
            var single2 = Singleton.Instance;
            Console.WriteLine(object.ReferenceEquals(single1, single2));
            Console.ReadLine();
        }
    }

    class Singleton
    {
        private static Singleton _Instance = null;
        private Singleton()
        {
            Console.WriteLine("Created");
        }

        public static Singleton Instance
        {
            get
            {
                if (_Instance == null)
                {
                    _Instance = new Singleton();
                }
                return _Instance;
            }
        }

        public void DumbMethod()
        {

        }
    }

这段代码忠实的实现了UML‘类图内里的一切’,“查看<输出>效果”,


“『证实』了”Singleton{确实起了作用},(多次挪)用仅仅产生了一个实例,似乎这么写就可以实现这个【模式】了。〖然则〗,(真的会“那么”简朴吗)?

(若是多线)程乱入?

现在我们给刚刚的例子加点调料,假设多个对实例的挪用,并不是简朴的,彬彬有礼的顺序关系,〖二是以多线程的方式挪〗用,“那么”刚刚那种 「实现方式」[,还能〖从〗容应对吗?【让我们试试】。〖把〗Main函数内里的挪用改成“这样”。

	static void Main(string[] args)
        {
            int TOTAL = 10000;
            Task[] tasks = new Task[TOTAL];
            for (int i = 0; i < TOTAL; i++)
            {
                tasks[i] = Task.Factory.StartNew(() =>
                {
                    Singleton.Instance.DumbMethod();
                });
            }
			Task.WaitAll(tasks);
            Console.ReadLine();
        }

{通过}Factory<缔造出>1《万个》Task,险些同时去请求这个单例,<看看<输出>>。

咦,我们刚刚写的Singleton“【模式】失效了”,(这个类被缔造了)5次(“这段代码运行多次”,“这个”数字不一定相同), 一定是多线程搞的鬼[,我们刚刚写的代码没有设施应对多线程,换句话说,「是非线程平安的」(thread-safe),那有没有设施来攻克这个难关呢?

<线程>平安的单例【模式】

Lock【‘‘版本’’】

“提到线程平安”,【许多同砚】第一反映就是用lock,『不错』,lock是个可行的设施,【让我们试试】。添加一个引用类型的工具作为lock工具,「『修改』代码如下」(“什么”?你问我为什必须是引用类型的工具而不能是值类型的工具?由于lock〖的时刻〗,若是工具是值类型,“那么”lock{仅仅锁住了它的一个副本},{另外一个线程可}以畅通无阻的再次lock,“这样”lock(就失去了壅闭线程的意义))

	private static object _SyncObj = new object();
        public static Singleton Instance
        {
            get
            {
                lock (_SyncObj)
                {
                    if (_Instance == null)
                    {
                        _Instance = new Singleton();
                    }
                    return _Instance;
                }                
            }
        }

{运行一下},<输出>

【只有一个实例建立】,『证实』Lock 起作用了[,这个【模式】可行!不外有些不喜欢用Lock的同砚可能要问,【另有没有其他设施呢】?谜底是有的。

静态组织器【‘‘版本’’】

《回忆一下》,C#中的类静态组织器,只会在这个类第一次被使用〖的时刻〗挪用一次,「自然的线程平安」,《那我们试试》不用Lock《使》用类静态组织器?『修改』Singleton类如下:

    class Singleton
    {
        private static Singleton _Instance = null;
        private Singleton()
        {
            Console.WriteLine("Created");
        }

        static Singleton()
        {
            _Instance = new Singleton();
        }

        //private static object _SyncObj = new object();
        public static Singleton Instance
        {
            get { return _Instance; }
        }

        public void DumbMethod()
        {

        }
    }

去掉了Lock,添加了一个类静态组织器,《试一试》。

完善! 对于不喜欢用[Lock(〖在这个〗例子中,实例只会建立一次〖然则〗之后的所有线程都要先排队Lock再进入Critical code{进行检查},效率对照低下)的同砚,类静态组织器提供了一种很好的选择。
不外俗话说,(人心苦不足) , 我们总是追求卓越。这个【‘‘版本’’】比Lock【‘‘版本’’】似乎更好一点,那另有没有更好的【‘‘版本’’】呢?有的。

Lazy【‘‘版本’’】

〖从〗net 4.0《最先》,C#《最先》支持延迟初始化,{通过}Lazy关键字,我们可以声明某个工具为仅仅当第一次使用〖的时刻〗,再初始化,若是一直没有挪用,那就不初始化,省去了一部分不必要的开销, 提升了效[率。 若是你不熟悉[Lazy或者想更多领会它,‘请参考’。我们今天关注的重点在于,Lazy‘也是天生线程’平安的,“以是我们实验用它来实现”Singleton【模式】?「『修改』代码如下」:

    class Singleton
    {
        private static Lazy<Singleton> _Instance = new Lazy<Singleton>(() => new Singleton());
        private Singleton()
        {
            Console.WriteLine("Created");
        }

        public static Singleton Instance
        {
            get
            {
                return _Instance.Value;
            }
        }

        public void DumbMethod()
        {

        }
    }

<输出>效果中可以看到,我们达到了想要的效果:

在上面的代码中,【私有变量】_Instance‘现在是被声明为延迟初始化’,“这样”不只自然实现了线程平安,同时在没有挪用Instance静态方式〖的时刻〗(也即没有挪用_Instance.Value),《初始化不会发生》,“这样”就提高了效率。

“总结”

Singleton【模式】很常见,【实现起来也很】简朴,只是要小心线程平安。{以上}三种方式都可以实现线程平安的Singleton【模式】。若是net 【‘‘版本’’】在4.0〖之上〗,【建议使用】Lazy【‘‘版本’’】,究竟对比Lock【‘‘版本’’】,Lazy【‘‘版本’’】可以免去实现手动Lock‘之苦’,对比Static【‘‘版本’’】,又有延迟初始化的性能优势,(何)乐而不为呢?

,

欧博网址开户

www.aidshuhehaote.com欢迎进入欧博网址(Allbet Gaming),欧博网址开放会员注册、【代理开户】、『电脑客户端下载』、【苹果安】卓下载等业务。

Allbet声明:该文看法仅代表作者自己,与本平台无关。转载请注明:环球ug官网:C#‘中的’Singleton{模式}

网友评论

  • (*)

最新评论

站点信息

  • 文章总数:1377
  • 页面总数:0
  • 分类总数:8
  • 标签总数:2432
  • 评论总数:260
  • 浏览总数:15314