文章目录

  • 1.什么是单例模式?
  • 2.什么时候要用单例模式呢?
  • 3.如何实现?
    • 3.1 普遍写法
    • 3.2 多线程的单例
      • 3.2.1 Lock关键字
      • 3.2.2 初步锁定实现
      • 3.2.3 双重锁定(Double -Check Locking)
    • 3.3 静态初始化
  • 4.拓展
    • 4.1 实用类和单例类的异同?
    • 4.2 单例的好处有哪些?
    • 4.3 为什么在unity中不用Lock?
    • 4.4 懒汉和饿汉的区别?
    • 4.5 我该使用懒汉还是饿汉?

说到单例模式想必大家都不陌生,为了加深自己对单例模式的理解,我又对单例模式进行了复习.(本节部分内容节选自大话设计模式第21章) 原文地址

1.什么是单例模式?

即保证一个类仅有一个实例,并提供有一个访问它的全局访问点.

2.什么时候要用单例模式呢?

通常我们可以让一个全局变量是的一个对象被访问,但它不能防止你实例化多个对象.此时一个最好的办法就是:让类自身负责保存它的唯一实例.这个类可以保证没有其他实例可以被创建,并且他可以提供一个访问该实例的方法.

3.如何实现?

3.1 普遍写法

先上一个较为普遍的写法(没错!他有很多写法,但万变不离其宗)

class Singleton{private static Singleton instace;//构造函数私有化,堵死外界利用new 创建本类实例的可能private Singleton()// 关于new关键字 和 构造函数可自行百度详细了解{ }public static Singleton GetInstace()//获取本类实例的唯一全局访问点{if (instace==null)//如果为null 则new一个实例出来,否则返回自己已有的实例{instace = new Singleton();}return instace;}}

调用方式:

 Singleton.GetInstace();

这里就不做过多解释了.

3.2 多线程的单例

当多线程程序中,多个线程同时访问Singleton类,调用GetInstance()方法,就会有可能创建出多个实例
这时候我们就需要lock关键字了.

3.2.1 Lock关键字

lock是确保当一个线程位于代码的临界区时,另一个线程不进入临界区.如果其他线程试图进入锁定的代码,则它将已知等待(即被阻止),知道该对象被释放.
结合下面代码,你会有一个更直观的感受.

3.2.2 初步锁定实现

class Singleton{private static Singleton instace;private Singleton(){ }private static readonly object syncRoot = new object();//程序运行时创建一个   静态   只读   的 进程辅助对象public static Singleton GetInstace(){lock (syncRoot)//在同一个时刻加入了锁的那部分程序只有一个线程可以进来{if (instace == null){instace = new Singleton();}}return instace;}}

这段代码使得对象实例由最先进入的那个线程创建,以后的线程在进入时不会再去创建对象实例了.由于有了lock,就保证了多线程环境下的同时访问也不会造成多个实例的生成.
但当你仔细观察,你就会发现另一个问题,每次GetInstance()时,都需要lock,是会影响性能的吧.所以就有了双重锁定

3.2.3 双重锁定(Double -Check Locking)

class Singleton{private static Singleton instace;private Singleton(){}private static readonly object syncRoot = new object();public static Singleton GetInstace(){if (instace == null)//先判断实例是否会存在,不存在再加锁处理{lock (syncRoot){if (instace == null){instace = new Singleton();}}}return instace;}}

细心的你可能已经发现了就多了一行代码.
可能你又会有疑问了:为什么在外面判断了instance是否存在,再加锁之后还要判断一次呢?
我们来一步一步分析

  1. 当第一个inatance不为空的时候,皆大欢喜 ,直接return
  2. 当第一个inatance为空的时候,同时又有两个进程来调用GetInstance()的时候,Lock开始真正起作用,先进来的进程,会new一次对象,当第一个进程结束,出去后,第二个进程继续进入,如果此时没有第二个"instance==null"的判断,第二个进程还是依然会继续new一次.并没有达到单例的目的了呀.

你品,你细品,是不是这个理?

3.3 静态初始化

C#与公共语言库也提供了一种静态初始化方法,这种方法不需要开发人员显式的编写线程安全代码,就可也解决多线程环境下它是不安全的问题.

 //sealed 关键字修饰类,叫做密封类   这里防止发生派生类,因为派生类可能会发生实例public sealed class Singleton{//在第一次引用类的任何成员时创建实例,公共语言运行库负责处理变量初始化private static readonly Singleton instance = new Singleton();private Singleton(){}public static Singleton GetInstace(){return instace;}}

4.拓展

4.1 实用类和单例类的异同?

当写到这里的时候是不是有些小伙伴就会有这样的疑问了?(不!我没有!!你不要强行安排我!!!)
这怎么和实用类的静态方法类似?比如你看看.Net的Math类,是不是很像???

同:实用类通常也会采取私有化构造函数来防止起有实例
异:
  1.实用类不保存状态,仅会提供一些静态方法和变量给你使用,但是单例类是会有状态的.
  2.实用类不能用于继承多态,而虽然单例类虽然唯一,但却可以有子类来继承.
  3.实用类只不过是一些方法属性的集合,而单例却是有唯一的对象实例.

4.2 单例的好处有哪些?

1.保证唯一的实例化
2.单例模式因为Singleton类封装他的唯一实例,这样它可以严格控制客户怎样访问和何时访问.简单来说就是对唯一实例的受控访问.

4.3 为什么在unity中不用Lock?

由于unity是主要是单线程的,所以通常对多线程并不关注.但并非是不用Lock,是用的比较少.
关于unity的多线程可以参考这篇文章,如果对unity多线程感兴趣的话可以抽时间详细去了解一下.

4.4 懒汉和饿汉的区别?

**懒汉:**在第一次引用就将自己实例化,被称为懒汉式单例.例如普遍写法那个模块的实现方式就是.
**饿汉:**当自己被加载时就将自己实例化,被称为饿汉式单例.例如静态初始化那个模块的实现方式就是.
差异:

饿汉式:是一种静态初始化的方式,他是类一加载就实例化对象,所以要提前占用系统资源.
懒汉式:会面临着多线程访问的安全性问题,需要做双重锁定这样的处理才能保证安全.

4.5 我该使用懒汉还是饿汉?

这种事情是根据实际需求而改变的.

  1. 对于unity开发者,如果不在多线程里使用的话,其实两者都可以,最好还是用懒汉模式,毕竟饿汉模式会提前占用内存
  2. 优先考虑线程安全问题的话,那就用饿汉模式好了.

大化设计模式-单例模式相关推荐

  1. Python设计模式-单例模式

    Python设计模式-单例模式 基于Python3.5.2,代码如下 #coding:utf-8 import threading import timeclass Singleton(object) ...

  2. Android设计模式——单例模式(Singleton)

    二十三种设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元 ...

  3. 【学习笔记】ABAP OOD设计模式 - 单例模式

    ABAP OOD设计模式 - 单例模式 整理转自-<SAP ABAP 面向对象程序设计(原则.模式及实践)> 单例模式(Singleton Pattern)是常用的且较为简单的软件设计模式 ...

  4. Go 语言实现 23 种设计模式 单例模式

    Go 语言实现 23 种设计模式 单例模式 单例模式 单例模式是一种常用的软件设计模式,在使用过程中,单例对象的类只有一个实例.使用单例模式,1 可以节省内存等资源,例如windows操作系统的资源管 ...

  5. java singleton inner class_Java面向对象设计模式-单例模式

    Java面向对象设计模式-单例模式 2020-05-28 589 0 单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点,有多重实现方式. 一.饿汉式单例模式,构造方法私有化,在加载类Sin ...

  6. Java开发中常用的设计模式-单例模式

    单例(Singleton)模式的定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式. Java开发中常用的设计模式-单例模式 单例模式有3个特点: 单例类只有一个实例对象: 该单例对象必须 ...

  7. 炒冷饭系列:设计模式 单例模式

    2019独角兽企业重金招聘Python工程师标准>>> 炒冷饭系列:设计模式 单例模式 摘要: 原创出处: http://www.cnblogs.com/Alandre/ 泥沙砖瓦浆 ...

  8. 设计模式-单例模式-注册式单例模式-枚举式单例模式和容器式单例模式在Java中的使用示例

    场景 设计模式-单例模式-饿汉式单例模式.懒汉式单例模式.静态内部类在Java中的使用示例: 设计模式-单例模式-饿汉式单例模式.懒汉式单例模式.静态内部类在Java中的使用示例_霸道流氓气质的博客- ...

  9. 设计模式----创建型设计模式(单例模式、工厂方法模式、构建者模式)

    创建型设计模式 单例模式(Singleton Pattern) 单例模式介绍 代码演示 饿汉式(静态常量) 饿汉式(静态代码块) 懒汉式(线程不安全) 懒汉式(线程安全,同步方法) 懒汉式(线程安全, ...

最新文章

  1. SAP MM MB21创建预留单据时候M标记能否自动勾选?
  2. Sentinel 1.5.0 正式发布,引入 Reactive 支持
  3. Android Settings开发之修改
  4. 锐捷服务器虚拟化技术_数据中心边缘虚拟交换(IEEE 802.1Qbg)技术白皮书
  5. PKUSC2018训练日程(4.18~5.30)
  6. 教你29招,让你在社交,职场上人人对你刮目相看
  7. 【nginx】【小记】泛解析大量域名的情况下 将不带www的域名,301到与之对应的www前缀的域名
  8. python从网址爬图片协程_python 用 gevent 协程抓取海量网页
  9. Integer中1000==1000为false而100==100为true
  10. 扫描线填充算法代码_手写算法并记住它:计数排序
  11. 【干货】python多进程和多线程谁更快
  12. Background Intelligent Transfer Service 服务错误(BITS服务失败) 的修复解决方案
  13. 掉价最快的手机排行榜_如何看待2020第一季度手机销量数据。
  14. 追赶法 c++代码实现
  15. 用python祝福父亲节_python 计算 父亲节
  16. 行测判断推理部分之图形推理(位置)
  17. 【实用代码】选项卡切换——带标题底纹样式
  18. 如何测量锂电池的电量
  19. 通过PaddleOCR识别PDF
  20. mblock——火焰灯

热门文章

  1. oracle vm3.4安装,受支持的平台 - Oracle® VM Server for SPARC 3.4 安装指南
  2. 明天要去阿里巴巴上班了,有点激动哦
  3. 没有基础或者基础差,如何快速学会编程?这4招绝对好使
  4. jquery attr(“xxx“,“mmm“)修改标签属性的值
  5. 二本计算机调剂学校,考研调剂接受二本学校的211大学
  6. iPhone Web服务器搭建(免越狱)--iSH
  7. es模糊查询汉字的问题
  8. (转)清华“差生”10年奋斗经历
  9. Container功能简述 java
  10. Rope一款轻量级别的ETL工具