码迷,mamicode.com
首页 > 其他好文 > 详细

创建型模式(四)单例模式

时间:2015-11-21 19:42:08      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:

 

一句话的概要

一个类只有一个实例,并提供一个全局访问点。

剧情

上回说到,屌丝小明同学跟女神完成了第一次的约会。女神很高兴,小明正准备下一次约会的时候。女神另一个追求者小刚也打算约女神出去。

但是女神就一个人,面对两个人的追求,只能是选择一个。另一个人只能说,抱歉了。

我们就以上剧情,使用单例模式,来进行演示。

任务一:创建女神

我们用单例的方法创建女神类,并让他第一次约有空,剩下均没有空。

public class Goddess
    {
        private Goddess() { Console.WriteLine("我有空,走吧"); }
        private static Goddess _Goddess;
        //创建全局访问点
        public static Goddess HelloGoddess() {
            if (_Goddess == null)
            {
                _Goddess = new Goddess();
            }
            else
            {
                Console.WriteLine("很抱歉,我没有时间");
            }
            return _Goddess;
        }
    }

首先,我们让他的实例变成私有。这样外部就无法调用了。

然后我们创建一个静态的变量,用来返回实例。

最后,我们创建全局访问点。来进行操作。

任务二:小明和小刚,分别邀请女神

小明先邀请女神,然后小刚在邀请女神。

static void Main(string[] args)
        {
            Console.Write("小明邀请女神:");
            Goddess xiaoming = Goddess.HelloGoddess();
            Console.Write("小刚邀请女神:");
            Goddess xiaogang = Goddess.HelloGoddess();

            Console.ReadLine();
        }

我们看看,运行结果

技术分享

小明捷足先登的约到了女神。小刚失利了。

这就是单例模式,如果你打算一直使用单线程并且不异步操作。那么这个完全是可以得。

但如果我们使用异步操作来调用的话,这个就不起作用了。我们下面来修改成异步操作。


女神类不进行修改。我们来修改小明和小刚,进行异步调用操作。

任务一:将小明、小刚提取成追求者类

使用await异步请求,进行调用操作。因为我懒得修改女神这个类了,所以我就加了一个等待时间。

public class Suitors {
        public async void Go() {
            Task xm = xiaoMing();
            Task xg = xiaoGang();
            await xm;
            await xg;
        }

        public async Task xiaoMing()
        {
            await Task.Delay(1000);
            Goddess girl = Goddess.HelloGoddess();
        }

        public async Task xiaoGang()
        {
            await Task.Delay(1000);
            Goddess girl = Goddess.HelloGoddess();
        }
    }

当我执行Go这个方法的时候,就会同时进行两个追求者的操作。那么就会产生下面这种情况。

技术分享

女神来者不拒啊~~~但我们知道,女神只能同意一个人的约会。所以我们再修改一下女神这个类。

任务二:修改女神类使用双重加锁模式

public class Goddess
    {
        private Goddess() { Console.WriteLine("我有空,走吧"); }
        private static Goddess _Goddess;
        private static object obj = new object();
        //创建全局访问点
        public static Goddess HelloGoddess() {
            if (_Goddess == null)
            {
                 lock(obj)
                {
                    if(_Goddess == null)
                        _Goddess = new Goddess();
                    else
                    {
                        Console.WriteLine("很抱歉,我没有时间");
                    }
                }
            }
            else
            {
                Console.WriteLine("很抱歉,我没有时间");
            }
            return _Goddess;
        }
    }

两个if中间一个lock,双重加锁。lock会锁定线程,一直到执行完毕。相关lock知识可以查看。点我

那么,我们的女神执行结果就变成了。

技术分享

小明同学,顺利约到女神。并且让情敌小刚碰了一鼻子灰。

总结

主要还是lock锁和全局访问点,这个模式还是好用的。

常用场景:要使用单例模式的对象,必须是全局且唯一。

选择关键点:一个对象如果出现多个实例,会不会引起逻辑上或程序上的错误。

 

创建型模式(四)单例模式

标签:

原文地址:http://www.cnblogs.com/chenxygx/p/4984322.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!