单例模式

一、简介

单例模式(Singleton Pattern)是软件设计中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

注意:

  • 1、单例类只能有一个实例。
  • 2、单例类必须自己创建自己的唯一实例。
  • 3、单例类必须给所有其他对象提供这一实例。

二、代码实现

1、懒汉模式

非线程安全。当正在创建时,有线程来访问此时LazyInstance = nil就会再创建,单例类就会有多个实例了。

var LazyInstance *Instance

func GetLazyInstance() *Instance {
if LazyInstance == nil {
LazyInstance = &Instance{
Counter: 0,
Name: "LazyInstance",
}
}
return LazyInstance
}

2、饿汉模式

初始化比较耗时间的话,获取的性能比较慢

var HungryInstance = &Instance{Name: "HungryInstance", Counter: 0}
func GetHungryInstance() *Instance {
return HungryInstance
}

3、改进型懒汉模式

每次读取都加锁了,比较好性能,更多的时候获取是不用加锁的

var mu sync.Mutex
var LazyInstancePlus *Instance
func GetLazyInstancePlus() *Instance {
mu.Lock()
defer mu.Unlock()
if LazyInstancePlus == nil {
LazyInstancePlus = &Instance{
Counter: 0,
Name: "LazyInstancePlus",
}
}
return LazyInstancePlus
}

只为空的时候加锁,提高了性能

var LazyInsPlusPlus *Instance

func GetLazyInsPlusPlus() *Instance {
if LazyInsPlusPlus == nil {
mu.Lock()
defer mu.Unlock()
LazyInsPlusPlus = &Instance{
Counter: 0,
Name: "LazyInsPlusPlus",
}
}
return LazyInsPlusPlus
}

4、 sync.once实现

var once sync.Once
var SyncOnceInstance *Instance func GetInstanceSyncOnce() *Instance {
once.Do(func() {
SyncOnceInstance = &Instance{
Counter: 0,
Name: "SyncOnceInstance",
}
})
return SyncOnceInstance
}

5、测试用例

package main

import (
"fmt"
"sync"
) type Instance struct {
Name string
Counter int //详细参数
} func (i *Instance) Hello() {
fmt.Printf("%s: my current counter is:%d\n", i.Name, i.Counter)
} //省略实现
func main() {
//懒汉模式测试
ls := GetLazyInstance()
ls.Hello()
ls.Counter += 1
ls1 := GetLazyInstance()
ls1.Hello() //饿汉模式测试
hs := GetHungryInstance()
hs.Hello()
hs.Counter += 10
hs1 := GetHungryInstance()
hs1.Hello() //改进型懒汉模式
lsp := GetLazyInstancePlus()
lsp.Hello()
lsp.Counter += 100
lsp1 := GetLazyInstancePlus()
lsp1.Hello() lspp := GetLazyInsPlusPlus()
lspp.Hello()
lspp.Counter += 1000
lspp1 := GetLazyInsPlusPlus()
lspp1.Hello() //sync once 测试
sc := GetInstanceSyncOnce()
sc.Hello()
sc.Counter += 10000
sc1 := GetInstanceSyncOnce()
sc1.Hello() }

结果:

LazyInstance: my current counter is:0
LazyInstance: my current counter is:1
HungryInstance: my current counter is:0
HungryInstance: my current counter is:10
LazyInstancePlus: my current counter is:0
LazyInstancePlus: my current counter is:100
LazyInsPlusPlus: my current counter is:0
LazyInsPlusPlus: my current counter is:1000
SyncOnceInstance: my current counter is:0
SyncOnceInstance: my current counter is:10000

完整代码和测试用例: https://gitee.com/ncuzhangben/GoStudy/tree/master/go-design-pattern/01-Singleton

[01]Go设计模式:单例模式(Singleton)的更多相关文章

  1. 设计模式 单例模式(Singleton) [ 转载2 ]

    设计模式 单例模式(Singleton) [ 转载2 ] @author java_my_life 单例模式的结构 单例模式的特点: 单例类只能有一个实例. 单例类必须自己创建自己的唯一实例. 单例类 ...

  2. 设计模式 单例模式(Singleton) [ 转载 ]

    设计模式 单例模式(Singleton) [ 转载 ] 转载请注明出处:http://cantellow.iteye.com/blog/838473 前言 懒汉:调用时才创建对象 饿汉:类初始化时就创 ...

  3. JAVA设计模式-单例模式(Singleton)线程安全与效率

    一,前言 单例模式详细大家都已经非常熟悉了,在文章单例模式的八种写法比较中,对单例模式的概念以及使用场景都做了很不错的说明.请在阅读本文之前,阅读一下这篇文章,因为本文就是按照这篇文章中的八种单例模式 ...

  4. 浅谈设计模式--单例模式(Singleton Pattern)

    题外话:好久没写blog,做知识归纳整理了.本来设计模式就是个坑,各种文章也写烂了.不过,不是自己写的东西,缺少点知识的存在感.目前还没做到光看即能记住,得写.所以准备跳入设计模式这个大坑. 开篇先贡 ...

  5. [工作中的设计模式]单例模式singleton

    一.模式解析: 单例模式是最简单和最常用的设计模式,面试的时候,不管新毕业的学生还是已经工作多年的筒子,对单例模式基本都能聊上两句.单例模式主要体现在如下方面: 1.类的构造函数私有化,保证外部不能直 ...

  6. 23种设计模式--单例模式-Singleton

    一.单例模式的介绍 单例模式简单说就是掌握系统的至高点,在程序中只实例化一次,这样就是单例模式,在系统比如说你是该系统的登录的第多少人,还有数据库的连接池等地方会使用,单例模式是最简单,最常用的模式之 ...

  7. 设计模式--单例模式Singleton(创建型)

    单例模式很显然是定义一个类,这个类在程序中只有唯一的实例对象.一般单例类的构造函数是私有的,只能通过调用静态函数GetInstance来获取实例. 一.单例模式有三种:懒汉式单例.饿汉式单例.登记式单 ...

  8. 设计模式--单例模式Singleton

    单例模式顾名思义整个程序下只有一个实例,例如一个国家只有一个皇帝,一个军队只有一个将军.单例模式的书写又分为饿汉模式和懒汉模式 饿汉模式   类中代码 package demo; public cla ...

  9. 设计模式——单例模式(Singleton)

    保证一个类仅有一个实例,并提供一个访问它的全局访问点.——DP UML类图 模式说明 个人认为单例模式是所有设计模式中最为简单的一个模式,因为实现这个模式仅需一个类,而不像其他模式需要若干个类.这个模 ...

随机推荐

  1. python_day3(文件处理)

    1.文件处理 #Author:Elson Zeng #data = open("test").read() # f = open("test",'a',enco ...

  2. canvas画圆环%显示

    我: JS代码:  function circleProgress(id,value,average){  var canvas = document.getElementById(id);  var ...

  3. jsp+servlet分页查询

    分页查询 减少服务器内存开销 提高用户体验 效果图 思绪图 分页显示Bean文件代码 package cn.ytmj.findlist.domain; import java.util.List; / ...

  4. git push后出现错误 ![rejected] master -> master(non-fast-forward) error:failed to push some refs to 'XXX'

    本地创建了一个project并在GitHub上创建了一个仓库,想要将本地的仓库链接到远程仓库我用的是如下方法:git init    //初始化本地仓库git remote add origin XX ...

  5. [JQuery] JQuery学习笔记

    1.2019年10月20日14:43:48 学习HOW2J. 2.JQuery是一个javascript的框架,是对javascript的一种封装, 通过JQuery可以非常方便的操作html的元素 ...

  6. 如何基于k8s快速搭建TeamCity(YAML分享)

    前言 最近有朋友基于之前的博客<Docker最全教程之使用TeamCity来完成内部CI.CD流程(十七)>搭建TeamCity时出现了一些问题,由于平常比较忙,没有及时答复,非常抱歉. ...

  7. DAGScheduler stage 划分算法

    DAGScheduler stage 划分算法 stage划分算法很重要,对于spark开发人员来说,必须对stage划分算法很清晰,知道自己编写的spark Application被划分成了几个jo ...

  8. nyoj 484-The Famous Clock

    484-The Famous Clock 内存限制:64MB 时间限制:1000ms 特判: No 通过数:2 提交数:2 难度:1 题目描述: Mr. B, Mr. G and Mr. M are ...

  9. Python print函数使用

    本文链接:https://www.cnblogs.com/zyuanlbj/p/11905405.html 函数定义 def print(self, *args, sep=' ', end='\n', ...

  10. systemd概念和运行机制

    systemd概念 核心概念:单元 依赖关系 systemd事务 启动目标和运行级别 单元 早期CentOS版本中的服务管理脚本在CentOS7中被服务但源文件替换.系统初始化需要启动后台服务,需要完 ...