[Go]-sync.map使用详解

在这里插入图片描述

sync.Map是 Go 语言中在并发环境下使用的安全映射类型。

一、为什么需要sync.Map

在 Go 语言中,普通的map不是并发安全的。当多个 goroutine 同时读写一个普通map时,可能会导致程序出现未定义的行为,比如数据竞争、程序崩溃等。而sync.Map则专门设计用于在并发环境下安全地进行读写操作。

二、主要方法

Store(key, value interface{}):存储一个键值对。将指定的keyvalue存储到sync.Map中。如果key已经存在,则会更新对应的值。

var m sync.Map
m.Store("key1", "value1")

Load(key interface{}) (value interface{}, ok bool):读取一个键对应的值。根据给定的keysync.Map中获取对应的值,如果key存在,则返回对应的值和true;如果key不存在,则返回nilfalse

value, ok := m.Load("key1")
if ok {fmt.Println(value)
}

Delete(key interface{}):删除一个键值对。根据给定的keysync.Map中删除对应的键值对。

m.Delete("key1")

Range(f func(key, value interface{}) bool):遍历sync.Map中的所有键值对。遍历过程中会对每个键值对调用传入的函数f,如果f返回false,则遍历停止。

m.Range(func(key, value interface{}) bool {fmt.Println(key, value)return true
})

三、使用场景

  1. 高并发场景下的缓存:在多个 goroutine 同时读写缓存数据时,sync.Map可以保证数据的一致性。
  2. 读多写少的情况:如果数据主要是读取操作,且写操作较少,比如缓存和配置管理。sync.Map 使用了无锁的快速路径来优化读取操作,因此在读多写少的场景下性能较好。
  3. 临时存储或共享数据:适合用于存储一些需要跨 goroutine 共享的数据,特别是临时数据或频繁更新的全局数据。
  4. 需要频繁扩展 key 的场景:当有很多动态 key 时,sync.Map 是一个不错的选择,因为它在增加新的 key 时不需要重新扩容,能避免频繁内存分配。
  5. 简单的缓存场景:在多 goroutine 并发访问的情况下,如果需要维护一个简单的缓存,可以使用 sync.Map 来存储缓存数据。比如在 HTTP 服务中,用于保存用户会话、请求状态等数据。
  6. 资源标识符映射场景:当需要维护某些资源标识符(如 ID、连接句柄等)到结构体实例的映射时,使用 sync.Map 可以减少锁的开销。
  7. 需要安全的删除和遍历sync.Map 提供了并发安全的 DeleteRange 方法,适合在需要频繁删除、查找和遍历的场景下使用。
  8. 并发结构体属性管理:可以用于并发安全地管理结构体的某些属性,例如计数器、状态信息等需要跨多个 goroutine 操作的字段。

不过,sync.Map 并不适合所有并发场景。对于读写比例相对均衡,且需要进行大量写操作的情况,使用传统的 map 搭配 sync.RWMutex 通常会表现得更好。

四、注意事项

  1. sync.Map的性能可能不如普通map在单线程环境下的性能高。如果你的程序不是在高并发环境下,使用普通map并配合适当的同步机制可能更合适。
  2. sync.Map返回的value是一个interface{}类型,在使用时需要进行类型断言,以确保获取到正确类型的值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/474999.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu22.04安装CH343驱动并创建udev规则

驱动说明 Linux系统提供CH34*系列 USB UART 设备配合使用的默认 CDC-ACM 驱动程序。驱动程序文件名为CDC-ACM。CDC-ACM 驱动程序控制特定设备的能力有限。此通用驱动程序不了解特定设备协议。因此,设备制造商可以创建能够访问设备特定功能集(例如硬件流…

Stable Diffusion经典应用场景

🌺系列文章推荐🌺 扩散模型系列文章正在持续的更新,更新节奏如下,先更新SD模型讲解,再更新相关的微调方法文章,敬请期待!!!(本文及其之前的文章均已更新&…

MATLAB常见数学运算函数

MATLAB中含有许多有用的函数,可以随时调用。 a b s abs abs函数 a b s abs abs函数在MATLAB中可以求绝对值,也可以求复数的模长:c e i l ceil ceil函数 向正无穷四舍五入(如果有小数,就向正方向进一)f l o o r floor floor函数 向负无穷四舍五入(如果有小数,就向负方向…

学习与理解LabVIEW中的格式化写入(Format into String)函数

有例子会更容易学习与理解LabVIEW中的函数 这是函数的基本介绍,下面我将以例子的方式介绍该函数: 初始字符串将会和已经填充好的格式化字符串拼接在一起,组成结果字符串,初始字符串在前。 应用: 可以用在执行SQL语句或…

Ubuntu22.04.2 k8s部署

k8s介绍 简单介绍 通俗易懂的解释: Kubernetes(也被称为 K8s)就像是一个大管家,帮你管理你的云计算服务。想象一下,你有很多个小程序(我们称之为“容器”),每个都在做不同的事情&…

oracle导入线上数据的全步骤

多租户架构允许oracle数据库成为一个多租户的容器数据库,也就是CDB,container database,与之相对应的,则是插入到这个容器里面的可插拔式数据库,pluggable database 一个CDB可以包含0,1或者多个用户创建的…

【机器学习】在泊松分布中,当λ值较大时,其近似正态分布的误差如何评估?

在泊松分布中,当参数 λ 较大时,其近似正态分布的有效性可以通过 中心极限定理 和误差分析来理解和评估。以下内容结合理论推导和实际案例展开说明: 1. 泊松分布的定义 泊松分布是用于建模单位时间或单位空间内随机事件发生次数的概率分布&a…

快速搭建Android开发环境:Docker部署docker-android并实现远程连接

目录 前言 1. 虚拟化环境检查 2. Android 模拟器部署 3. Ubuntu安装Cpolar 4. 配置公网地址 5. 远程访问 小结 6. 固定Cpolar公网地址 7. 固定地址访问 作者简介: 懒大王敲代码,计算机专业应届生 今天给大家聊聊快速搭建Android开发环境&#x…

使用 SMB 协议从win10电脑访问同网段ubuntu电脑文件

​​​​​​1.在 Ubuntu 上设置共享文件夹 在终端中运行以下命令安装 Samba: sudo apt update sudo apt install samba 编辑 Samba 配置文件: sudo nano /etc/samba/smb.conf 在文件末尾添加以下内容(假设要共享 用户dy下的Downloads目录&…

Android WMS概览

WMS(WindowManagerService)是 Android 系统的核心服务,负责管理应用和系统的窗口,包括窗口的创建、销毁、布局、层级管理、输入事件分发以及动画显示等。它通过协调 InputManager 和 SurfaceFlinger 实现触摸事件处理和窗口渲染&a…

25.<Spring博客系统②(实现JWT令牌登录接口+强制登录+获取用户信息+获取作者信息)>

PS:带删除线的方法 可以使用但是不建议使用(方法提供方说的) 加上Deprecated注解。就代表这个方法可以使用,但是不建议使用。也就会带删除线了 前言 对于用户登录。 我们之前的做法都是 1.用户登录,后端验证用户名和密…

《Python编程实训快速上手》第七天--文件与文件路径

该章节将使用Python在硬盘上创建、读取和保存文件 一、文件与文件路径 1、Windows中使用\以及macOS和Linux中使用/ 使用pathlib模块中的Path()函数进行文件名和目录的拼接,返回文件路径字符串 from pathlib import Path print(Path("spam","bacon",&qu…

Oracle RAC仲裁交换机的小科普

一、Oracle RAC仲裁交换机的主要功能 Oracle RAC仲裁交换机是用于Oracle Real Application Clusters(真实应用集群,简称RAC)环境中的一种网络设备。它主要用于在集群节点之间进行通信,以确保集群的高可用性和故障切换能力。以下是…

Leetcode 快乐数

算法思想: 这段代码的目的是判断一个正整数是否是 快乐数(Happy Number)。根据题目要求,快乐数定义如下: 对于一个正整数,不断将它每个位上的数字替换为这些数字平方和。重复这个过程,如果最终…

使用 Vue 和 Create-Vue 构建工程化前端项目

目录 前言1. 工程化的意义与 Vue 的生态支持2. 搭建 Vue 工程化项目2.1 环境准备2.2 使用 create-vue 创建项目2.2.1 初始化项目2.2.2 安装依赖2.2.3 本地运行 3. Vue 项目的目录结构解析4. Vue 开发流程详解4.1 项目入口与根组件4.1.1 main.js 的作用4.1.2 App.vue 的结构 4.2…

【MySQL实战45讲笔记】基础篇——redo log 和 binlog

系列文章 基础篇——MySQL 的基础架构 目录 系列文章1. 重要的日志模块:redo log 和 binlog1.1 redo log1.2 binlog1.3 执行器和 InnoDB 引擎内部如何执行更新语句 1. 重要的日志模块:redo log 和 binlog 前面系统的了解了一个查询语句的执行流程&…

C++ lambda(匿名函数)捕获自己

今天写算法题时无意间遇到一种情况,我的深度优先遍历函数要在函数内调用自身,如果是普通函数没什么问题,但如果是 匿名函数 的话会有一些问题,甚至问ai,ai也没打上来,上网搜了半天,才找到这个的解答,故作此文 以费契那波数列为例 // 普通函数式 int fun(int pos) {if (pos …

DAO模式

前言 DAO(Data Access Object)模式 是一种常用的设计模式,主要用于将数据访问逻辑与业务逻辑分离。它提供了一种抽象层,使得应用程序可以与不同的数据源(如数据库、文件系统等)进行交互,而无需…

mysql日志写满出现The table ‘xxxx_amazon_order’ is full

数仓发现写数据出现 SQL 错误 [1114] [HY000]: The table ‘xxxx_amazon_order’ is full 1.第一时间查看系统磁盘, 发现空间写满了 df -h因为mysql是使用docker部署的, Docker 的默认存储位置在 /var/lib/docker /var 目录默认是在根分区 (/dev/mapper/centos-root) 下的 …

【读书笔记-《网络是怎样连接的》- 7】Chapter3_2 路由器

本篇继续介绍路由器及其转发过程。 1 路由器内部结构 路由器内部结构图如图所示。 即主要包含左侧的包转发模块和右侧的端口模块。转发模块负责查找包的发送目的地,端口模块完成包的发送。通过安装不同的硬件,转发模块不仅可以支持以太网,也…