本文来自于本人个人微信公众号,欢迎关注本人微信公众号,二维码附在文章末尾~~~

一直都特别羡慕能写文章的人,但是由于本人比较懒再加上写文章功底实在是just so so,所以就一搁再搁,最近突然觉得自己的技术能力好像很长时间都停滞不前,有一种隐隐的危机感,所以不得不逼自己一把。我写文章的目的主要是对自己一个学习的总结,情感的抒发以及生活的记录,顺便提高自己的文字功底与技术能力,当然如果能帮助到别人那自然是极好的,哈哈!!!

下面就开始我的第一篇微信公众文章内容啦,文章中涉及代码的部分以C#为主。

  1. 单例模式的特点

    顾名思义,单例类只能生成一个实例,且我们必须把单例类的构造函数设为私有函数以禁止他人创建实例,即,单例类只能自己创建自己的唯一实例,其他所有对象都使用这个实例。

  2. 单例模式的结构

  3. 下面通过几种不同的解法做对比来更深入的了解单例模式

    解法1:只适用于单线程环境的解法

解法1中Singleton的静态属性Instance中只有instance为null时才创建一个实例以避免重复创建,同时我们把构造函数定义为私有函数,这样确保只创建一个实例。

缺点:只满足单线程,多线程下会有问题,如两个线程同时运行到判断instance是否为null的if语句,并且instance的确没有创建时,那么两个线程都会创建一个实例,此时解法一中的Singleton就不满足单例模式了

解法2:适用于多线程,但效率不高

解法2中通过添加同步锁解决了多线程环境下的单例模式,由于在一个时刻只有一个线程能得到同步锁,当第一个线程加上锁时,第二个线程只能等待,当第一个线程发现实例没有创建时,它创建一个实例,接着第一个线程释放同步锁,此时第二个线程可以加上同步锁运行代码,但是此时实例已经被创建,第二个实例就不会再创建实例了,这样保证在多线程下只能创建一个实例

缺点:在每次通过属性Instance得到Singleton的实例都会试图加上一个同步锁,而加锁是一个非常耗时的操作,在非必要情况下要避免

解法3:加同步锁前后两次判断实例是否已存在

解法3中Singleton2中只有当instance为null即没有创建时需要加锁操作,当instance已经创建出来之后则无需加锁,因为只在第一次的时候instance为null,所以只在第一次试图创建实例的时候需要加锁,这样比解法2中的效率就高出很多。

缺点:解法3中用加锁机制来确保在多线程环境下只创建一个实例,并且用两个if来判断来提高效率,这样的代码实现起来比较容易出错。

解法4:利用静态构造函数

解法4是比较推荐的解法,代码非常简洁,我们在初始化静态变量instance的时候创建一个实例,由于C#在调用静态构造函数时初始化静态变量,.NET运行时能够确保只调用一次静态构造函数,这样能保证只初始化一次instance。

缺点:.NET第一次运行使用Singleton3时会自动调用该类型的静态构造函数,所以instance不是在第一次调用Singleton.instance被创建,而是在第一次用到Singleton3的时候被创建,会导致在单例模式中过早的创建实例,从而降低内存的使用效率。

解法5:实现按需创建实例

解法5中我们在内部定义了一个私有类型Nested,当第一次用到这个嵌套类型的时候,会调用静态构造函数创建Singleton4的instance实例。类型Nested只在属性Singleton4.instance中被用到,由于其私有属性他人无法使用Nested类型,因此当我们第一次试图通过属性Singleton4.instance得到Singleton4的实例时,会自动调用Nested的静态构造函数创建instance。如果我们不调用instance,那么就不会触发.NET运行时调用Nested,也不好创建实例,这样就真正做到了按需创建。

综上五种解法,推荐解法4和解法5,单例模式是面试中的"常客",是设计模式中最简单的,看完了这篇文章是不是发现so easy 呐,好啦,今天就写到这儿,这就是我的第一篇微信公众号文章啦,欢迎吐槽,我已经做好了在吐槽中成长的准备啦~~~~~~~~

特别声明:

本文内容参考于书籍《剑指Offer-名企面试官精讲典型编程题》何海涛(著)

欢迎关注本人个人微信公众号

设计模式之单例模式(C#)的更多相关文章

  1. 设计模式之单例模式(Singleton)

    设计模式之单例模式(Singleton) 设计模式是前辈的一些经验总结之后的精髓,学习设计模式可以针对不同的问题给出更加优雅的解答 单例模式可分为俩种:懒汉模式和饿汉模式.俩种模式分别有不同的优势和缺 ...

  2. GJM : C#设计模式(1)——单例模式

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

  3. java设计模式之单例模式(几种写法及比较)

    概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...

  4. 每天一个设计模式-4 单例模式(Singleton)

    每天一个设计模式-4 单例模式(Singleton) 1.实际生活的例子 有一天,你的自行车的某个螺丝钉松了,修车铺离你家比较远,而附近的五金店有卖扳手:因此,你决定去五金店买一个扳手,自己把螺丝钉固 ...

  5. 设计模式之单例模式的简单demo

    /* * 设计模式之单例模式的简单demo */ class Single { /* * 创建一个本类对象. * 和get/set方法思想一样,类不能直接调用对象 * 所以用private限制权限 * ...

  6. 设计模式之单例模式——Singleton

                        设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有 ...

  7. 10月27日PHP加载类、设计模式(单例模式和工厂模式)、面向对象的六大原则

    加载类可以使用include.require.require_once三种中的任意一种,每个关键字都有两种方法,但是这种方法的缺点是需要加载多少个php文件,就要写多少个加载类的方法.一般也就需要加载 ...

  8. java 23 - 2 设计模式之单例模式

    单例模式:保证类在内存中只有一个对象. 如何保证类在内存中只有一个对象呢?  A:把构造方法私有  B:在成员位置自己创建一个对象  C:通过一个公共的方法提供访问 单例模式之饿汉式: (一进来就造对 ...

  9. [转]JAVA设计模式之单例模式

    原文地址:http://blog.csdn.net/jason0539/article/details/23297037 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主 ...

  10. python_way,day8 面向对象【多态、成员--字段 方法 属性、成员修饰符、特殊成员、异常处理、设计模式之单例模式、模块:isinstance、issubclass】

    python_way day8 一.面向对象三大特性: 多态 二.面向对象中的成员 字段.方法属性 三.成员修饰符 四.特殊成员 __init__.__doc__.__call__.__setitem ...

随机推荐

  1. coTurn测试程序之turnutils_stunclient.exe

    测试使用方法,作为STUN客户端,仅用于测试STUN服务是否正常运行. 使用coTurn服务启动STUN/TURN服务后,执行以下命令即可: turnutils_stunclient -p 61.18 ...

  2. VMware安装Centos7后有线线缆被拔出

    背景:在win10 系统中的虚机软件VMware Workstation中安装CentOS7桌面版,安装过程中没有设置网络 1.确认你win10系统打开了这两个服务:VMware DHCP Servi ...

  3. OPPO A57 刷机(官方安装包)+完美Root+ 破解主题+屏蔽Root顶部红色框+NV修复

    朋友说她的手机被被人刷后,有许多预装的软件问我能不能处理下,让我装个纯净版. 开机可以看到预装了许多软件,通常想要删除预装软件就必须Root,于是下载刷机精灵,360刷机大师,线刷包之类的软件Root ...

  4. [20170612]FOR ALL COLUMNS SIZE repeat(11g).txt

    [20170612]FOR ALL COLUMNS SIZE repeat(11g).txt --//昨天看了https://jonathanlewis.wordpress.com/2017/06/0 ...

  5. 语句调优基础知识-set statistics io on

    set statistics io on --清空缓存数据 dbcc dropcleanbuffers go --清空缓存计划 dbcc freeproccache go set statistics ...

  6. SqlServer跨集群升级

    SqlServer跨集群升级 1.新Server的IP要和旧的在同一网段. 2.安装SQL SERVER(注意:排序要和以前的一样,更改TempDB位置) 3.开启防火墙,并打开1433和5022端口 ...

  7. 【Git 学习三】深入理解git reset 命令

    重置命令(git reset)是Git 最常用的命令之一,也是最危险最容易误用的命令.来看看git reset命令用法. --------------------------------------- ...

  8. TP中的图片水印

    $img_dir = ROOT_PATH . 'public/upload/card/' . $data['jt_id']; //创建合成图片存放位置 //自动创建文件夹 if (!file_exis ...

  9. SQLServer插入数据

    使用数据库管理工具插入数据 打开数据库,选则要插入数据的表->右键点击->选择插入前200行->在右边视图中输入要插入的数据(如果字段设置为不为空,则必须输入,如果字段设置为可空,则 ...

  10. Python 中两个字典(dict)合并

    dict1 = { "name":"owen", "age": 18 } dict2 = { "birthday": & ...