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,可能会导致性能下降,因此需要根据实际场景选择使用。

相关文章
|
5月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
305 2
|
7月前
|
Cloud Native 安全 Java
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
442 1
|
7月前
|
Cloud Native Go API
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
496 0
|
7月前
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
336 0
|
7月前
|
Cloud Native Java 中间件
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
374 0
|
7月前
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
421 0
|
7月前
|
数据采集 Go API
Go语言实战案例:多协程并发下载网页内容
本文是《Go语言100个实战案例 · 网络与并发篇》第6篇,讲解如何使用 Goroutine 和 Channel 实现多协程并发抓取网页内容,提升网络请求效率。通过实战掌握高并发编程技巧,构建爬虫、内容聚合器等工具,涵盖 WaitGroup、超时控制、错误处理等核心知识点。
|
7月前
|
数据采集 消息中间件 编解码
Go语言实战案例:使用 Goroutine 并发打印
本文通过简单案例讲解 Go 语言核心并发模型 Goroutine,涵盖协程启动、输出控制、主程序退出机制,并结合 sync.WaitGroup 实现并发任务同步,帮助理解 Go 并发设计思想与实际应用。
|
Go
Go 语言学习之map
Go 语言学习之map
164 0
|
Go
go语言基础数据结构学习 ---- 字典(map)
go语言基础数据结构学习 ---- 字典(map)
293 0

热门文章

最新文章