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

单例模式

单例模式是一种常用的软件设计模式,在使用过程中,单例对象的类只有一个实例。使用单例模式,1 可以节省内存等资源,例如windows操作系统的资源管理器只有一个就够了。2 方便配置管理,例如,服务器的配置信息存放在一个文件中,配置信息由一个单例实例统一读取,进场中的其他对象通过这个单例实例获取配置信息。

实例1

下面这段代码有什么问题,从多线程角度思考,就会发现下面的代码是非线程安全的,比如有两个线程都在调用NewInstance1函数,线程A在执行到if instance==nil后 cpu切换到线程B执行,直到线程B运行完,这时instance已经被实例化,当cpu在切回到线程A继续执行的时候,对instance又执行实例化操作,这时内存中已有Instance的两个实例,违背了单例定义。

type Instance struct{}//非线程安全
func NewInstance1() *Instance {if instance == nil {instance = &Instance{}}return instance
}

实例2

var lock sync.Mutex//lock-check模式
func NewInstance2() *Instance {lock.Lock()defer lock.Unlock()if instance == nil {instance = &Instance{}}return instance
}

实例3

实例3采用的是先判断方式,如果instance已经被实例化,直接返回就行了。如果没有实例化,在进行加锁创建实例,即执行实例2的操作。这样就可以并发执行。上面的实例2是先lock在check方式,简称lock-check模式,实例称为check-lock-check模式。继续思考,实例3有没有问题呢?if instance==nil是原子操作吗?

//check-lock-check模式
func NewInstance3() *Instance {if instance == nil {lock.Lock()if instance == nil {instance = &Instance{}}lock.Unlock()}return instance
}

实例4

既然实例3 比较操作是非原子操作,那将比较这句改成原子操作,golang 提供了原子操作package atomic,申请一个uint32变量做标记,如果是1表示已实例化,如果是0表示么有实例化。实例4已经非常好了,在golang有么有更好的方法呢,

var initlized uint32//check-lock-check
func NewInstance4() *Instance {if atomic.LoadUint32(&initlized) == 1 {return instance}lock.Lock()defer lock.Unlock()if initlized == 0 {instance = &Instance{}atomic.StoreUint32(&initlized, 1)}return instance}

实例5

在golang中,atomic包中提供一个sync.Once类型,该类型有个Do方法,只会执行一次,
所以将实例化方法放在Do中,只会实例化一次,非常完美的方法,所以实例5是最佳实践方法。

func NewInstance5() *Instance {if instance == nil {once.Do(func() {instance = &Instance{}})}return instance
}

分析总结

在写代码的时候,要保证正确性第一,然后在考虑性能优化的问题,实例1和实例3在正确性上没有保证。
其次才是考虑性能优化,有没有更好的方法,像实例2性能不友好,实例4就比实例2有提升,实例5是最佳实践方法。
当然实例3方法可以放在init函数中调用,进程启动之后再掉用其实也没有问题,因为instance已经被实例化过了。

程序的运行中只产生一个实例

Example_one

type Singleton struct {id int
}var TestSingleton *Singleton
var singletonMutex sync.Mutexfunc NewSingleton() *Singleton {if TestSingleton == nil {singletonMutex.Lock()defer singletonMutex.Unlock()if TestSingleton == nil {TestSingleton = &Singleton{0}}}return TestSingleton
}

Example_two

func NewSingleton() *Singleton {once.Do(func() {TestSingleton = &Singleton{0}})return TestSingleton
}

Go 语言实现 23 种设计模式 单例模式相关推荐

  1. Go 语言实现 23 种设计模式适配器

    Go 语言实现 23 种设计模式适配器 将一个类型的接口转换成客户希望的另外一个接口,使原本由于接口不兼容而不能一起工作的类可以一起工作. Example_one package mainimport ...

  2. java 的23种设计模式 单例模式

    23种设计模式友情链接: 点击打开链接 单例模式: A.饿汉式单例模式 具体步骤: 1.声明一个私有的静态的最终的本类类型的对象并实例化 private static final Person ins ...

  3. 【设计模式】| 修炼内功 | 23种设计模式——单例模式

    设计模式如同织锦之艺术,精心构筑,展示优美. 学习设计模式,犹如追逐清晨的曙光,扉页掀开了人生的新篇章.当你学会设计模式的奥秘,就如同走进了灯火通明的城市,丰富多彩的建筑,让你大开眼界,拥有了整个世界 ...

  4. Go 语言实现 23 种设计模式(修饰器)

    修饰器 修饰器模式就是在不改变对象内部结构的情况下,动态扩展它的功能. Example_one type Object func(string) stringfunc Decorate(fn Obje ...

  5. java外围设计_Java 编程(23 种设计模式)

    简介 在一般的程序开发过程中,初中级程序员接触的程序设计模式是比较少的.最常见的可能就是单例模式.工厂模式.抽象工厂模式等等,但实际上程序中的设计模式是非常多的,具体可以分为 23 种设计模式.设计模 ...

  6. 设计模式—23种设计模式

    23种设计模式 单例模式 工厂模式 抽象工厂模式 模板方法模式 建造者模式 代理模式 原型模式 中介者模式 命令模式 责任链模式 装饰模式 策略模式 适配器模式 迭代器模式 组合模式 观察者模式 门面 ...

  7. 23种设计模式在MMORPG游戏中的应用

    设计原则和设计模式是软件工程领域的两个重要概念,设计原则提供了编写高质量.可维护代码的指导思想,而设计模式则为特定问题提供了经过验证的解决方案.下面是7大设计原则和23种设计模式的总结: 7大设计原则 ...

  8. 23种设计模式[1]:单例模式

    前言:  听说懂设计模式的Developer工资会高很多?最近面试也被问到熟悉设计模式有哪些?于是便有此文. 语言背景:PHP.Java 定义:确保一个类只有一个实例,而且自行实例化并向整个系统提供这 ...

  9. 快来,这里有23种设计模式的Go语言实现

    摘要:设计模式(Design Pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结,使用设计模式是为了可重用代码.让代码更容易被他人理解并且保证代码可靠性. 本文分享自华 ...

最新文章

  1. codevs——1019 集合论与图论
  2. 编译安装keepalived-1.2.2.tar.gz报错处理
  3. Shell-bash
  4. 安装maven之后,cmd提示mvn不是内部命令的解决办法
  5. 【移动开发】Android中三种超实用的滑屏方式汇总(ViewPager、ViewFlipper、ViewFlow)...
  6. abort has been called
  7. 学生专用计算机如何打游戏,电竞专业学生日常:白天学语数外计算机,晚上才打游戏...
  8. 6张信用卡欠款10000到47000不等,会被起诉坐牢吗?
  9. 中蒙俄经济走廊背景_上海外国语大学师生代表团参观访问G60科创走廊俄罗斯院士创新基地...
  10. 玩具谜题(洛谷-P1563)
  11. 谷歌:中国版搜索引擎之心不死!
  12. 设计模式之构造函数模式
  13. 今天,我需要你的支持!
  14. Vue 路由的模块化
  15. Go语言grpc proto生成pb文件
  16. 北大方正集团名列2018年中国电子信息百强第8位
  17. 802.11 - 灵活组播服务(Flexible multicast service)
  18. 轻流入选|国际权威研究机构「2021年低代码平台中国市场现状分析报告」发布
  19. 四人小组:vip会员管理系统
  20. 关于移动端的touch事件(touchstart, touchmove, touchend,touchcancel)

热门文章

  1. 从条纹边框的实现谈盒子模型
  2. 7-12(图) 社交网络图中结点的“重要性”计算(30 分)
  3. wcf rest系列文章
  4. 总线接口与计算机通信
  5. ODAC(V9.5.15) 学习笔记(四)TCustomDADataSet(2)
  6. paip.最新的c++ qt5.1.1环境搭建跟hello world
  7. .Net Remoting(基本操作) - Part.2 (转)
  8. 再谈VC++中ListControl排序[原创]
  9. matlab impdt,实验1 基于Matlab的数字信号处理基本操作
  10. php 四维数组_PHP 多维数组