当前位置: 首页 > news >正文

Golang学习笔记_27——单例模式

Golang学习笔记_24——泛型
Golang学习笔记_25——协程Golang学习笔记_25——协程
Golang学习笔记_26——通道


文章目录

    • 单例模式
      • 1. 介绍
      • 2. 应用场景
      • 3. 实现
        • 3.1 饿汉式
        • 3.2 懒汉模式
    • 源码


单例模式

1. 介绍

单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。

这种模式在很多场景下非常有用,比如数据库连接池、日志系统等,这些场景中我们通常希望在整个应用程序中只有一个对象来负责相关的操作,避免资源的浪费和数据的不一致

2. 应用场景

  • 数据库连接池:在应用程序中,数据库连接的创建和销毁是比较消耗资源的操作。使用单例模式可以确保整个应用程序只有一个数据库连接池实例,多个地方需要获取数据库连接时都从这个连接池中获取,这样可以有效地管理数据库连接,提高性能并节省资源。
  • 日志系统:一个应用程序通常只需要一个日志记录器来统一记录各种操作信息。单例模式可以保证整个系统只有一个日志记录器实例,所有的日志记录操作都通过这个实例来完成,方便对日志进行统一管理和配置。
  • 配置管理:对于应用程序的配置信息,如服务器端口号、数据库连接参数等,使用单例模式可以确保整个应用程序只有一个配置管理实例,这样可以方便地在不同的模块中获取和修改配置信息,并且保证配置信息的一致性。

3. 实现

3.1 饿汉式
type Singleton struct{}var singleInstance *Singleton = &Singleton{}func GetInstance() *Singleton {return singleInstance
}func test1() {instance1 := GetInstance()instance2 := GetInstance()fmt.Println(instance1 == instance2)
}

说明
这种方式在程序启动时就初始化了单例实例singleInstance。&Singleton{}创建了一个Singleton结构体的实例,并将其赋值给singleInstance。

GetInstance函数只是简单地返回这个已经初始化好的实例。这种方式被称为饿汉式,因为实例是在程序开始时就 “急切” 地创建好了,而不管是否马上会被用到。

优点是实现简单,并且在多线程环境下也是安全的,因为实例在任何线程访问之前就已经创建好了。

缺点是如果单例的初始化过程很复杂或者资源消耗大,可能会导致程序启动变慢。

3.2 懒汉模式

线程不安全


type Singleton struct{}var singleInstance *Singleton
// 懒汉式(非线程安全)
func GetInstance2() *Singleton {fmt.Println("GetInstance2")if singleInstance == nil {singleInstance = &Singleton{}}return singleInstance
}func test1() {
instance1 := GetInstance()
instance2 := GetInstance()
fmt.Println(instance1 == instance2)
}

懒汉式单例模式。在GetInstance函数中,首先检查singleInstance是否为nil。如果是,就创建一个Singleton结构体的新实例并赋值给singleInstance,然后返回这个实例

线程安全

type Singleton struct{}var singleInstance *Singleton// 懒汉式(线程安全)
var mutex sync.Mutexfunc GetInstance3() *Singleton {fmt.Println("GetInstance3")mutex.Lock()defer mutex.Unlock()if singleInstance == nil {singleInstance = &Singleton{}}return singleInstance
}func test1() {
instance1 := GetInstance()
instance2 := GetInstance()
fmt.Println(instance1 == instance2)
}

为了在多线程环境下正确地实现懒汉式单例模式,引入了互斥锁sync.Mutex

在GetInstance函数中,首先调用mutex.Lock()获取锁,这确保了同一时刻只有一个线程能够进入临界区

使用defer mutex.Unlock()可以保证在函数返回之前释放锁。这样,即使多个线程同时调用GetInstance函数,也能保证只有一个线程会创建singleInstance实例,从而保证了单例模式的正确性。

type Singleton struct{}var singleInstance *Singletonvar once sync.Oncefunc GetInstance4() *Singleton {fmt.Println("GetInstance4")once.Do(func() {fmt.Println("just once!")singleInstance = &Singleton{}})return singleInstance
}func test1() {
instance1 := GetInstance()
instance2 := GetInstance()
fmt.Println(instance1 == instance2)
}

once.Do 方法会确保传入的匿名函数只会被执行一次

源码

package singletonimport ("fmt""sync"
)type Singleton struct{}// 饿汉式
// var singleInstance *Singleton = &Singleton{} // 懒汉式直接在程序运行时创建
func GetInstance1() *Singleton {fmt.Println("GetInstance1")return singleInstance
}var singleInstance *Singleton// 懒汉式(非线程安全)
func GetInstance2() *Singleton {fmt.Println("GetInstance2")if singleInstance == nil {singleInstance = &Singleton{}}return singleInstance
}// 懒汉式(线程安全)
var mutex sync.Mutexfunc GetInstance3() *Singleton {fmt.Println("GetInstance3")mutex.Lock()defer mutex.Unlock()if singleInstance == nil {singleInstance = &Singleton{}}return singleInstance
}// 使用sync.Once实现
var once sync.Oncefunc GetInstance4() *Singleton {fmt.Println("GetInstance4")once.Do(func() {fmt.Println("just once!")singleInstance = &Singleton{}})return singleInstance
}// 测试方法
func test1() {//instance1 := GetInstance1()//instance2 := GetInstance1()//instance1 := GetInstance2()//instance2 := GetInstance2()//instance1 := GetInstance3()//instance2 := GetInstance3()instance1 := GetInstance4()instance2 := GetInstance4()fmt.Println(instance1 == instance2)
}

相关文章:

Golang学习笔记_27——单例模式

Golang学习笔记_24——泛型 Golang学习笔记_25——协程Golang学习笔记_25——协程 Golang学习笔记_26——通道 文章目录 单例模式1. 介绍2. 应用场景3. 实现3.1 饿汉式3.2 懒汉模式 源码 单例模式 1. 介绍 单例模式是一种创建型设计模式,它确保一个类只有一个实例…...

хорошо哈拉少wordpress俄语主题

хорошо哈拉少wordpress俄语主题 wordpress俄文网站模板,推荐做俄罗斯市场的外贸公司建俄语独立站使用。 演示 https://www.jianzhanpress.com/?p7360...

[数据结构与算法]js实现二叉树

DFS 与 BFS dfs 递归 本质通过栈结构 bfs 层序遍历 通过队列结构 function permute(nums) {let res [];let cur []; // 记录当前内容let visted {}; //记录访问过的节点let len nums.length;function dfs(nth) {//递归终止条件if (nth len) {res.push([...cur]);return …...

MySQL程序之:连接到服务器的命令选项

本节介绍大多数MySQL客户端程序支持的选项,这些选项控制客户端程序如何建立与服务器的连接、连接是否加密以及连接是否压缩。这些选项可以在命令行或选项文件中给出。 连接建立的命令选项 本节介绍控制客户端程序如何建立与服务器的连接的选项。 表6.4连接建立选…...

python3GUI--仿崩坏三二次元登录页面(附下载地址) By:PyQt5

文章目录 一.前言二.预览三.实现方案1.实现原理1.PyQt52. 具体实现 2.UI设计1.UI组件化、模块化2.UI设计风格思路 3.项目代码结构4.使用方法3.代码分享1.支持跳转网页的QLabel组件2.三角形ICON按钮 四.总结 大小:33.3 …...

阿里云 Serverless 助力盟主直播:高并发下的稳定性和成本优化

在直播场景中,阿里云 Serverless 应用引擎 SAE 提供的无缝弹性伸缩与极速部署能力,确保直播间高并发时的流畅体验,降低了我们的运营成本,简化了运维流程。结合阿里云云原生数据库 PolarDB 的 Serverless 能力,实现了数…...

Unity 学习指南与资料分享

Unity学习资料 Unity学习资料 Unity学习资料 Unity 作为一款强大的跨平台游戏开发引擎,在游戏开发及实时 3D 内容创作领域占据着重要地位。它功能丰富、易于上手,支持多平台发布,为开发者提供了广阔的创作空间。下面为你带来全面的 Unity 学…...

Android SystemUI——CarSystemBar视图解析(十一)

前面文章我们已经把 CarSystemBar 从启动到构建视图,再到将视图添加到 Window 的流程分析完毕,我们知道默认情况下在车载系统中只显示顶部栏和底部栏视图的。这里我们在前面文章的基础上以顶部栏为例具体解析其视图的结构。 一、顶部栏解析 通过《CarSystemBar车载状态栏》这…...

.NET周刊【1月第1期 2025-01-05】

国内文章 3款.NET开源、功能强大的通讯调试工具,效率提升利器! https://www.cnblogs.com/Can-daydayup/p/18631410 本文介绍了三款功能强大的.NET开源通讯调试工具,旨在提高调试效率。这些工具包括LLCOM,提供串口调试和自动化处…...

初识go语言之指针用法

一、环境准备 安装go语言编译环境,官网地址:https://go.dev/dl/ 或者 https://golang.google.cn/dl/ 点击下载按提示安装即可 vscode 安装go语言扩展 测试 package mainimport "fmt"func main() {fmt.Println("Hello, World!") …...

用户中心项目教程(二)---umi3的使用出现的错误

目录 1.情况的说明 2.遇到的问题 1)第一个问题-关于npx的使用 2)第二个问题--unsupport问题 3)第三个收获--nodejs安装问题 4)第四个收获---nvm下载问题 5)第五个问题--尚未解决的问题 3.个人总结 1.情况的说明…...

Android设备:Linux远程gdb调试

更多内容:XiaoJ的知识星球 目录 1.准备工作1)安装Android NDK:2)连接Android手机3)编译程序 2.启动gdbserver1)**推送gdbserver及可执行文件**:**2)启动gdbserver**:3&am…...

(十四)WebGL纹理坐标初识

纹理坐标是 WebGL 中将 2D 图像(纹理)应用到 3D 物体表面的重要概念。在 WebGL 中,纹理坐标通常使用一个二维坐标系,称为 uv 坐标,它们决定了纹理图像如何映射到几何体上。理解纹理坐标的核心就是明白它们如何将二维纹…...

【机器学习】制造业转型:机器学习如何推动工业 4.0 的深度发展

我的个人主页 我的领域:人工智能篇,希望能帮助到大家!!!👍点赞 收藏❤ 引言 在当今科技飞速发展的时代,制造业正经历着前所未有的变革,工业4.0的浪潮席卷而来。工业4.0旨在通过将…...

Nginx安装配置Mac使用Nginx访问前端打包项目

目录 Linux安装环境变量配置 WinMac安装基本配置 Mac使用Nginx访问前端项目常用命令 Linux 官网:https://nginx.org/ 中文官网:https://nginx.p2hp.com/ 安装 http://nginx.org/en/download.html 1). 安装依赖包 由于nginx是基于c语言开发的&#x…...

国自然面上项目|基于组合机器学习算法的病理性近视眼底多模态影像资料自动化定量分析研究|基金申请·25-01-18

小罗碎碎念 今天和大家分享一个面上项目,资助年限为2020~2023,直接费用为55万。 病理性近视致盲问题严峻,机制和诊疗策略尚待探索。本项目基于前期积累的大量影像资料和算法开发工作,计划构建标准影像数据库&#xff0…...

03_UI自适应

因为Canvas大小是始终和屏幕一致的 所以设置Canvas的屏幕大小 通常设置为1920 * 1080 又因为屏幕的图像及按钮如果想适配各种显示屏需要锁定长或者宽, 之后利用钉子将其他图像利用创建空节点定在左右或者上下两侧 比如unity编辑器通常是锁定宽的,那我…...

Python在DevOps中的应用:自动化CI/CD管道的实现

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在现代软件开发中,DevOps理念的引入极大地提升了开发与运维的协作效率,而持续集成&#xff08…...

API接口技术推动电商数据处理的自动化

在当今数字化浪潮中,电商行业正以前所未有的速度发展。API(Application Programming Interface,应用程序编程接口)接口技术在这一过程中扮演着至关重要的角色。API接口作为连接不同系统和服务的关键桥梁,通过其自动化处…...

Nginx反向代理架构介绍

Nginx反向代理架构是一种强大的服务器架构模式,它位于用户和原始服务器之间,接收用户的请求并将其转发到一个或多个后端服务器,然后将从后端服务器获取的响应返回给用户,就好像这些内容都是由代理服务器本身直接提供的一样。以下是…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...