单例模式-Golang实现

2023-10-27

非线程安全的懒汉模式

main.go

package simple

import (
	"fmt"
	"sync"
	"time"
)

var singleton *Singleton

type Singleton struct {
}

func getInstance(wg *sync.WaitGroup) *Singleton {
	defer wg.Done()
	if nil == singleton {
		fmt.Println("init ")
		time.Sleep(time.Second)
		singleton = &Singleton{}
	}
	return singleton
}

simple_test.go

package simple

import (
	"sync"
	"testing"
)

var (
	wg sync.WaitGroup
)

func TestSimple(t *testing.T) {
	for i := 0; i < 30; i++ {
		wg.Add(1)
		go getInstance(&wg)
	}
	wg.Done()
}

image-20220105202604177

线程安全的懒汉模式

使用sync.Mutex 互斥锁实现

main.go

package main

import (
	"sync"
)

var wg sync.WaitGroup

func main() {
	for i := 0; i < 30; i++ {
		wg.Add(1)
		go getInstance()
	}
	wg.Wait()
}

single.go

package main

import (
	"fmt"
	"sync"
	"time"
)

type Singleton struct {
}

var (
	mu       sync.Mutex
	instance *Singleton
)

func getInstance() *Singleton {
	defer wg.Done()
	if nil == instance {
		mu.Lock()
		defer mu.Unlock()
		if nil == instance {
			fmt.Println("init")
			time.Sleep(time.Second)
			instance = &Singleton{}
		}
	}
	return instance
}

使用sync.Once实现

single.go

package main

import (
	"fmt"
	"sync"
	"time"
)

type single struct{}

var instance *single
var once sync.Once

func getInstance(wg *sync.WaitGroup) *single {
	defer wg.Done()
	once.Do(func() {
		fmt.Println("初始化了")
		time.Sleep(time.Second)
		instance = &single{}
	})
	return instance
}

single_test.go

package main

import (
	"sync"
	"testing"
)

var wg sync.WaitGroup

func TestSingleton(t *testing.T) {
	for i := 0; i < 30; i++ {
		wg.Add(1)
		go getInstance(&wg)
	}
	wg.Wait()
}

sync.Once源码

package sync

import (
	"sync/atomic"
)

type Once struct {
	done uint32
	m    Mutex
}

func (o *Once) Do(f func()) {
	if atomic.LoadUint32(&o.done) == 0 {
		o.doSlow(f)
	}
}

func (o *Once) doSlow(f func()) {
	o.m.Lock()
	defer o.m.Unlock()
	if o.done == 0 {
		defer atomic.StoreUint32(&o.done, 1)
		f()
	}
}

由于互斥锁的开销较大,sync.Once利用sync/atomic包下的原子操作函数检测标志位来降低互斥锁的使用次数来提高性能

饿汉模式

hungry_test.go

package hungry

import (
	"fmt"
	"testing"
)

func TestHungry(t *testing.T) {
	s := GetInstance()
	fmt.Println(s)
}

single.go

package hungry

type singleton struct {
}

var instance *singleton = &singleton{}

func GetInstance() *singleton {
	return instance
}

比较懒汉模式和饿汉模式

懒汉模式就是在有调用的情况下才会去做初始化,若无调用就不做初始化

饿汉模式一般在程序加载起来的时候就要做初始化,无论是否调用

懒汉模式为了保证不重复创建实例,需要判空,然而所做的判空在并发情况下会同时通过判空条件,重复创建实例。所以说懒汉模式存在线程安全问题

问题就是可能会有多个线程同时进入创建实例的代码部分, 所以程序要做保证创建实例部分代码的原子性

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单例模式-Golang实现 的相关文章

  • 离散仿真引擎基础作业与练习

    作业内容 一 简答题 1 解释 GameObjects 和 Assets 的区别与联系 2 下载几个游戏案例 分别总结资源 对象组织的结构 3 使用 debug 验证 MonoBehaviour 基本行为或事件触发条件 4 了解 GameO
  • 【数据结构】堆、栈的区别

    heap 是堆 stack 是栈 在编程语言中 内存分配方式主要包括 栈 堆 静态存储分配 栈的内存是由操作系统自动分配 释放的 存放函数的参数值 局部变量等 堆的内存是由程序员手动申请和释放的 对应C语言中的malloc函数和C 中的ne
  • 设计模式学习笔记(一)之单例模式

    单例模式 作用 保证一个类只有一个实例 并且提供访问这个实例的全局访问点 应用场景有 数据库连接池 spring中 Bean默认是单例 Servlet中 每一个Servlet是单例 配置文件的类 一般是单例 优点 单例只生成一个实例 减少系
  • 设计模式——原型模式

    原型模式顾名思义 就是指以某个实例为原型 copy出一个新的实例 该实例属性与原型相同或者是类似 很多时候 我们需要创建大量的相同或者相似的对象 如果一个个用new 构造函数的形式去创建的话比较繁琐 就像孙悟空要想变出成千上万个猴子猴孙总不
  • 简单工厂模式

    简单工厂模式 一 概念 从设计模式的类型上来说 简单工厂模式是属于创建型模式 又叫做静态工厂方法 StaticFactory Method 模式 但不属于23种GOF设计模式之一 简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例 简
  • C++设计模式-State状态模式

    State状态模式作用 当一个对象的内在状态改变时允许改变其行为 这个对象看起来像是改变了其类 UML图如下 State类 抽象状态类 定义一个接口以封装与Context的一个特定状态相关的行为 ConcreteState类 具体状态 每一
  • [C++]备忘录模式

    备忘录模式 Memento Pattern 保存一个对象的某个状态 以便在适当的时候恢复对象 备忘录模式属于行为型模式 github源码路径 https github com dangwei 90 Design Mode 此文件包含 mai
  • 设计模式-建造者模式

    文章目录 建造者模式 创建复杂对象的优雅方式 什么是建造者模式 建造者模式的使用场景 优缺点 示例 使用建造者模式创建电脑对象 建造者模式 创建复杂对象的优雅方式 在软件开发中 有时候我们需要创建具有复杂结构和多个组件的对象 直接在客户端代
  • 设计模式七大原则

    1 设计模式的目的 编写软件过程中 程序员面临着来自耦合性 内聚性以及可维护性 可扩展性 重用性 灵活性 等多方面的挑战 设计模式是为了让程序 软件 具有更好 1 代码重用性 即 相同功能的代码 不用多次编写 2 可读性 即 编程规范性 便
  • 设计模式(十)装饰器模式

    装饰器模式是一种非常有用的结构型模式 它允许我们在不改变类的结果的情况下 为类添加新的功能 我们来举例说明一下 首先添加一组形状 它们都实现了形状接口 public interface Shape String getShape class
  • 设计模式(5)-适配器模式(Adapter Pattern)

    适配器模式 Adapter Pattern 顾名思义 就像变压器 转接头差不多 就像美国的生活电压是110V 中国是220V 就需要一个变压器将220V转换成110V 或者一个Type C接口想插如USB接口的东西 你就需要一个转换器 而这
  • 分享几个项目中用到的设计模式

    前言 之前项目中出于扩展性和有雅性的考虑 使用了多种设计模式进行项目框架的设计 主要的一些设计模式是单例模式 工厂模式 策略模式 责任链模式 代理模式这几种 现在依次讲讲这几个的主要是实现方式和在我们项目中的应用场景 核心设计模式分享 单例
  • [C++]外观模式

    外观模式 Facade Pattern 隐藏系统的复杂性 并向客户端提供了一个客户端可以访问系统的接口 这种类型的设计模式属于结构型模式 它向现有的系统添加一个接口 来隐藏系统的复杂性 这种模式涉及到一个单一的类 该类提供了客户端请求的简化
  • Java设计模式:模板方法模式

    作者主页 欢迎来到我的技术博客 个人介绍 大家好 本人热衷于 Java后端开发 欢迎来交流学习哦 如果文章对您有帮助 记得 关注 点赞 收藏 评论 您的支持将是我创作的动力 让我们一起加油进步吧 文章目录 一 模板方法模式的定义 二 模板方
  • 设计模式 原型模式 与 Spring 原型模式源码解析(包含Bean的创建过程)

    原创 疯狂的狮子Li 狮子领域 程序圈 2023 12 19 10 30 发表于辽宁 原型模式 原型模式 Prototype模式 是指 用原型实例指定创建对象的种类 并且通过拷贝这些原型 创建新的对象 原型模式是一种创建型设计模式 允许一个
  • 设计模式 原型模式 与 Spring 原型模式源码解析(包含Bean的创建过程)

    原创 疯狂的狮子Li 狮子领域 程序圈 2023 12 19 10 30 发表于辽宁 原型模式 原型模式 Prototype模式 是指 用原型实例指定创建对象的种类 并且通过拷贝这些原型 创建新的对象 原型模式是一种创建型设计模式 允许一个
  • 自动化测试面试题(附答案)

    1 自动化代码中 用到了哪些设计模式 单例设计模式 工厂模式 PO设计模式 数据驱动模式 面向接口编程设计模式 2 什么是断言 Assert 断言Assert用于在代码中验证实际结果是不是符合预期结果 如果测试用例执行失败会抛出异常并提供断
  • 计算机基础:网络基础

    一 网线制作 1 制作所需要工具 网线 网线制作标准 2 水晶头使用 3 网线钳使用 4 视频教学 网线制作 二 集线器 交换机介绍 1 OSI七层模型 Open System Interconnect 即开放系统互连参考模型 是由 ISO
  • C++设计模式 #3策略模式(Strategy Method)

    动机 在软件构建过程中 某些对象使用的的算法可能多种多样 经常改变 如果将这些算法都写在类中 会使得类变得异常复杂 而且有时候支持不频繁使用的算法也是性能负担 如何在运行时根据需求透明地更改对象的算法 将算法和对象本身解耦 从而避免上述问题
  • 计算机基础:网络基础

    一 网线制作 1 制作所需要工具 网线 网线制作标准 2 水晶头使用 3 网线钳使用 4 视频教学 网线制作 二 集线器 交换机介绍 1 OSI七层模型 Open System Interconnect 即开放系统互连参考模型 是由 ISO

随机推荐

  • word图片撑满_word图片满页 word图片铺满整个页面

    word中如何让图片占满整个页面 确定 再确定 不OK了 7厘米 页面设置 里设置页面方向及纸张大小 当然也要根据你打印机性能 请将下面 锁定纵横比 那个钩取消 如将页面边距设置为0 点 版式 如图片太大你打印机不一定打印得了 再点右下角的
  • Python报错:IndexError: invalid index of a 0-dim tensor. Use `tensor.item()` in

    Python报错如下 E anaconda envs pytorch gpu python exe D project graphsage graphsage model py D project graphsage graphsage e
  • 自动找Bug/插件-代码静态检查findbugs-idea安装以及使用

    目录 简介 IDEA安装FindBugs Findbugs配置 配置排除一些类 扫描级别 IDEA中使用FindBugs 一些常见错误 补充 简介 Findbugs是一个静态分析工具 它检查类或者JAR 文件 将字节码与一组缺陷模式进行对比
  • 闲谈云计算

    其实一直到处看到关于云计算的东西和话题 云计算一直是一个很火的关键字 最近几天才有时间找来一本 云那些事 来看看 只是很粗略的看了关于云计算发展方向的一些问题 具体的云技术是一盘丰盛的大餐 得慢慢吃 其实我一直在没有认真去看云计算的时候 觉
  • Future和FutureTask用法详细介绍

    Future和FutureTask 文章目录 Future和FutureTask Future FutureTask Demo code output 在并发编程中 多线程的实现有继承Thread和Runnable 因为单继承的原因我们往往
  • Java阿里巴巴代码规范

    目录 1 编程规约 1 1 方法参数类型必须一致 不要出现自动装箱拆箱操作 1 1 1 反例 1 1 2 正例 1 2 SimpleDateFormat是线程不安全的 1 2 1 反例 1 2 2 正例 1 3 使用equals方法应该注意
  • 软件项目管理(第二版 宁涛)问答题(个人背诵)

    目录 第一章 概述 1 什么是软件项目管理 2 项目管理的 9 大知识领域是什么 3 项目管理的 5 个过程组是什么 5 项目经理的主要职责是什么 6 项目的特点是什么 7 项目和运营的共同点有哪些 8 项目集成管理是什么 9 规划过程组的
  • Flutter学习 — 从新页面返回数据给上一个页面

    效果图一 点击按钮 效果图二 点击YES后 返回上一级页面并传值 效果图三 收到值 并用底部弹出框显示结果 注释 代码 import package flutter material dart void main runApp new Ma
  • 关于Git的一点思考

    GIT历史 很多人都知道 Linus在1991年创建了开源的Linux 从此 Linux系统不断发展 已经成为最大的服务器系统软件了 Linus虽然创建了Linux 但Linux的壮大是靠全世界热心的志愿者参与的 这么多人在世界各地为Lin
  • YOLOV5之TensorRT模型部署

    目录 一 环境版本 1 1 概述 1 2 Ubuntu版本 1 3 python pytorch与tensorrt版本 1 4 cudnn版本 1 5 驱动版本 1 6 opencv版本 二 TensorRT与opencv环境安装 2 1
  • 虚拟化概念详解

    虚拟化的定义 虚拟化技术可以认为是一种对物理资源抽象化 进而形成虚拟化的版本的技术 虚拟化的目的 物理资源组成庞大的资源池 然后可以按需分配 随意切割物理资源 虚拟化资源分类 服务器虚拟化 服务器虚拟化就是将虚拟化技术应用于服务器 将一台服
  • 【STM32标准库】【基础知识】ADC转换,非DMA的单通道和多通道

    文章目录 ADC概述 ADC初始化 GPIO初始化 时钟 全局ADC设置 定义结构体 是否使用DMA 工作模式 分频 采样延迟 例程 单独ADC设置 定义结构体 连续转换 数据对齐 外部触发 通道数量 分辨率 扫描模式 例程 设置规则 打开
  • 【Git】(五)切换分支

    1 切换分支 git checkout newBranch 2 如果需要保留本地修改 git status git add git commit amend git checkout newBranch 3 强制切换分支 放弃本地修改 强制
  • vgg16-pytorch

    基于pytorch实现VGG16模型 刚听完土哥的入门pytorch 试着写一个不完善的vgg16 VGG16具体的架构 VGG16模型构建 卷积池化后尺寸计算公式 引入库 from torch import nn from torch n
  • 深入理解java虚拟机(十) Java 虚拟机运行时栈帧结构

    运行时栈帧结构 栈帧 Stack Frame 是用于虚拟机执行时方法调用和方法执行时的数据结构 它是虚拟栈数据区的组成元素 每一个方法从调用到方法返回都对应着一个栈帧入栈出栈的过程 每一个栈帧在编译程序代码的时候所需要多大的局部变量表 多深
  • <5>STM32库函文件分析-库函数

    使用STM32F10x的库函数文件编程就要对它的库文件有一个相对清晰的认识 即使不能做到知根知底 但当要使用到MCU的某个功能时 要知道相应的库函数在哪个对应的 h和 c 文件中 看懂并了解它的寄存器 下面我写一下我对其的认知 有错误的地方
  • SQLMAP工具 详细使用方法

    文章目录 SQLMAP简介 SQLMAP支持的注入模式 SQLMAP支持的数据库 SQLMAP安装 Linux Windows 更新 SQLMAP参数详解 使用 Options Target Reques Optimization Inje
  • UnityShader入门精要——透明物体阴影

    透明度测试 Shader Unity Shaders Book Chapter 9 Alpha Test With Shadow Properties Color Color Tint Color 1 1 1 1 MainTex Main
  • 2023最新软件测试面试题(带答案)

    1 请自我介绍一下 需简单清楚的表述自已的基本情况 在这过程中要展现出自信 对工作有激情 上进 好学 面试官您好 我叫 今年26岁 来自江西九江 就读专业是电子商务 毕业后就来深圳工作 有三年的软件测试工程师的经验 我性格比较开朗 能和同事
  • 单例模式-Golang实现

    目录 非线程安全的懒汉模式 线程安全的懒汉模式 使用sync Mutex 互斥锁实现 使用sync Once实现 饿汉模式 比较懒汉模式和饿汉模式 非线程安全的懒汉模式 main go package simple import fmt s