Go 语言中的 Sync.Map 详解:并发安全的 Map 实现

简介: `sync.Map` 是 Go 语言中用于并发安全操作的 Map 实现,适用于读多写少的场景。它通过两个底层 Map(`read` 和 `dirty`)实现读写分离,提供高效的读性能。主要方法包括 `Store`、`Load`、`Delete` 等。在大量写入时性能可能下降,需谨慎选择使用场景。

1. Sync.Map 的必要性

在 Go 语言中,标准的 map 类型并不是线程安全的。在多个 goroutine 并发访问时,需要使用锁来保护数据。为了解决这个问题,Go 语言在 1.9 版本中引入了 sync.Map,它是一个并发安全的 Map 实现,可以在多个 goroutine 中安全地读写数据。

为什么Map的并发是不安全的?

2. Sync.Map 的底层原理

sync.Map 底层使用了两个原生的 Map:一个是 read,用于读操作,另一个是 dirty,用于写操作。其中,read 可视为“高速缓存”,当 goroutine 从 sync.Map 中读数据时,会首先查看 read 这个缓存层是否有用户需要的数据。如果有,则通过原子操作将数据读取并返回,这是 sync.Map 的快路径,也是其读性能极高的原因。

写操作直接写入 dirty,而 读操作则先读 read,如果没有命中,则再读 dirty

image.png

3. 适用场景

sync.Map 适用于以下两种场景:

  • 写少读多:例如缓存,只写一次,读取多次。
  • 多个 goroutine 操作不同 key:多个 goroutine 读取、写入和覆盖不相交的 key 集的条目。

因为大量写入的时候,会导致read map读不到数据而进一步加锁读取,同时dirty map也会一直晋升为read map,整体性能差,不如map + mutex

4. Sync.Map 的方法

sync.Map 提供了以下几个方法:

  • Store(key, value any):向 Map 中存储键值对。
  • Load(key any):根据键获取值。
  • Delete(key any):删除键值对。
  • LoadAndDelete(key any):获取并删除键值对。
  • LoadOrStore(key, value any):如果 key 已经存在,返回对应值,如果不存在,存储键值对。
  • Range(f func(key, value any) bool):遍历 Map 中的键值对。

5.代码实现

image.png

总结

sync.Map 是 Go 语言中一个非常实用的并发安全的 Map 实现,特别适用于读多写少的场景。通过其底层的读写分离机制,sync.Map 提供了高效的读性能和简洁的使用方式。然而,在大量写入的情况下,由于需要频繁更新 read,可能会导致性能下降,因此需要根据实际场景选择使用。

相关文章
|
11月前
|
存储 JavaScript Java
(Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
dict字典 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 我们可以通过声明JS对象一样的方式声明dict
545 2
|
存储 人工智能 安全
深入理解 go sync.Map - 基本原理
本文介绍了 Go 语言中 `map` 在并发使用时的常见问题及其解决方案,重点对比了 `sync.Mutex`、`sync.RWMutex` 和 `sync.Map` 的性能差异及适用场景。文章指出,普通 `map` 不支持并发读写,容易引发错误;而 `sync.Map` 通过原子操作和优化设计,在某些场景下能显著提升性能。同时详细讲解了 `sync.Map` 的基本用法及其适合的应用环境,如读多写少或不同 goroutine 操作不同键的场景。
619 1
|
存储 安全 Go
Map的遍历与判断键是否存在-《Go语言实战指南》
本文介绍了 Go 语言中对 `map` 的常见操作,包括遍历所有项和判断键是否存在。通过 `for range` 可以遍历 `map` 的键值对、仅键或仅值(需忽略键)。注意,`map` 遍历顺序是随机的。判断键是否存在时,使用双赋值语法 `value, ok := map[key]`,其中 `ok` 表示键是否存在。直接访问不存在的键会返回类型的零值,可能导致逻辑错误。掌握这些机制可更安全高效地处理键值对数据。
|
存储 安全 Go
Go语言中的map数据结构是如何实现的?
Go 语言中的 `map` 是基于哈希表实现的键值对数据结构,支持快速查找、插入和删除操作。其原理涉及哈希函数、桶(Bucket)、动态扩容和哈希冲突处理等关键机制,平均时间复杂度为 O(1)。为了确保线程安全,Go 提供了 `sync.Map` 类型,通过分段锁实现并发访问的安全性。示例代码展示了如何使用自定义结构体和切片模拟 `map` 功能,以及如何使用 `sync.Map` 进行线程安全的操作。
642 9
|
安全 Java 数据库连接
让我们讲解一下 Map 集合遍历的方式
我是小假 期待与你的下一次相遇 ~
452 43
|
存储 前端开发 API
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用
该文章详细介绍了ES6中Set和Map数据结构的特性和使用方法,并探讨了它们在前端开发中的具体应用,包括如何利用这些数据结构来解决常见的编程问题。
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用
|
存储 安全 Java
java集合框架复习----(4)Map、List、set
这篇文章是Java集合框架的复习总结,重点介绍了Map集合的特点和HashMap的使用,以及Collections工具类的使用示例,同时回顾了List、Set和Map集合的概念和特点,以及Collection工具类的作用。
java集合框架复习----(4)Map、List、set
|
Go 定位技术 索引
Go 语言Map(集合) | 19
Go 语言Map(集合) | 19
【Java集合类面试二十二】、Map和Set有什么区别?
该CSDN博客文章讨论了Map和Set的区别,但提供的内容摘要并未直接解释这两种集合类型的差异。通常,Map是一种键值对集合,提供通过键快速检索值的能力,而Set是一个不允许重复元素的集合。

热门文章

最新文章