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

一句话的概要

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

剧情

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

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

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

任务一:创建女神

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

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锁和全局访问点,这个模式还是好用的。

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

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

时间: 2024-08-08 21:55:09

创建型模式(四)单例模式的相关文章

创建型模式:单例模式

文章首发:创建型模式:单例模式 简介 姓名:单例模式 英文名:Singleton Pattern 价值观:我的生活我主宰(只允许自己实例化,不愿意被其他对象实例化) 个人介绍: Ensure a class has only one instance, and provide a global point of access to it.(确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.)(来自<设计模式之禅>) 这里的关注点有 3 个,分别是: 只有一个实例 自行实例化(也

3创建型模式之单例模式

概念 单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象.也就是说,在整个程序空间中,该类只存在一个实例对象. GoF对单例模式的定义是:保证一个类.只有一个实例存在,同时提供能对该实例加以访问的全局访问方法. 为什么使用单例模式? 在应用系统开发中,我们常常有以下需求: - 在多个线程之间,比如初始化一次socket资源:比如servlet环境,共享同一个资源或者操作同一个对象 - 在整个程序空间使用全局变量,共享资源 - 大规模系统中,为了性能的考虑,需要节省对

Python版设计模式: 创建型模式:单例模式和工厂模式家族

一. 单例模式(Singleton) 所谓单例模式,也就是说不管什么时候都要确保只有一个对象实例存在.很多情况下,整个系统中只需要存在一个对象,所有的信息都从这个对象获取,比如系统的配置对象,或者是线程池.这些场景下,就非常适合使用单例模式. 总结起来,就是说不管初始化一个对象多少次,真正干活的对象只会生成一次并且在首次生成. 用Python 实现单例模式的方法有很多,先来看第一种方式. # !/usr/bin/python3 # -*- coding:utf-8 -*- class singl

4创建型模式之单例模式__多线程下的懒汉式单例和饿汉式单例

//1"懒汉"模式虽然有优点,但是每次调用GetInstance()静态方法时,必须判断 //      NULL == m_instance,使程序相对开销增大. //2多线程中会导致多个实例的产生,从而导致运行代码不正确以及内存的泄露. //3提供释放资源的函数 讨论:   这是因为C++中构造函数并不是线程安全的. C++中的构造函数简单来说分两步: 第一步:内存分配 第二步:初始化成员变量 由于多线程的关系,可能当我们在分配内存好了以后,还没来得急初始化成员变量,就进行线程切换

【设计模式】创建型模式之单例模式(三)

单例模式 单例模式,是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中,应用该模式的一个类只有一个实例.即一个类只有一个对象实例. 简单的理解:保证这一个类仅有一个实例,并提供一个访问它的全局访问点. 通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象.一个最好的办法就是,让类自身负责保存它的唯一实例.这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法. 实现思路 将该类的构造方法定义为私有方法,这样其

(创建型模式四)创建者模式

package com.eyugame.modle; /** * 创建者模式 * * @author JYC506 * */ /*导演者*/ public class Director { IBuilder myBuilder=new MyBuilder(); public PhoneProduct createMiPhone() { myBuilder.setNameAndType("小米", "note"); myBuilder.des("售价2300

创建型模式之单例模式

单例模式,英文原话为:Ensure a class has only one instance, and provide a gloabal point of access to it;即:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 单例模式的主要作用是:确保一个类只有一个实例存在.单例模式可以用在建立目录.数据库连接等需要单线程操作的场合,用于实现对系统资源的控制. 单例模式又有两种表现形式:饿汉式单例,类加载时实例化对象:懒汉式单例,第一次引用时实例化对象.两种表现形式

设计模式_创建型模式_单例模式_案例

转载自:http://blog.csdn.net/lovelion  作者:刘伟 负载均衡器的设计与实现 Sunny公司开发人员通过分析和权衡,决定使用单例模式来设计该负载均衡器,结构图如图3-3所示: 在图中,将负载均衡器LoadBalancer设计为单例类,其中包含一个存储服务器信息的集合serverList, 每次在serverList中随机选择一台服务器来响应客户端的请求,实现代码如下所示: LoadBalance: 1 namespace SingletonPattern 2 { 3

Java设计模式——创建型模式之单例模式

一.概述 作为第一个出场的设计模式,有必要先介绍一下设计模式(引用自百度百科): 设计模式(Design Pattern)是一套被反复使用.多数人知晓的.经过分类的.代码设计经验的总结. 使用设计模式的目的:为了代码可重用性.让代码更容易被他人理解.保证代码可靠性. 设计模式使代码编写真正工程化:设计模式是软件工程的基石脉络,如同大厦的结构一样. 设计模式概念的介绍,参见:http://blog.jobbole.com/101076/ 其中涉及的设计原则的概念,参见随笔:http://www.c

php设计模式(一):简介及创建型模式

我们分三篇文章来总结一下设计模式在PHP中的应用,这是第一篇创建型模式. 一.设计模式简介 首先我们来认识一下什么是设计模式: 设计模式是一套被反复使用.容易被他人理解的.可靠的代码设计经验的总结. 设计模式不是Java的专利,我们用面向对象的方法在PHP里也能很好的使用23种设计模式. 那么我们常说的架构.框架和设计模式有什么关系呢? 架构是一套体系结构,是项目的整体解决方案:框架是可供复用的半成品软件,是具体程序代码.架构一般会涉及到采用什么样的框架来加速和优化某部分问题的解决,而好的框架代