Go - 使用 sync.Map 来解决 map 的并发操作问题

简介: Go - 使用 sync.Map 来解决 map 的并发操作问题

文章目录:

  • 前言
  • map 并发操作出现问题
  • sync.Map 解决并发操作问题
  • 计算 map 长度
  • 计算 sync.Map 长度
  • 小结
  • 推荐阅读


前言

Golangmap 不是并发安全的,自 1.9 才引入了 sync.Mapsync.Map 的引入确实解决了 map 的并发安全问题,不过 sync.Map 却没有实现 len() 函数,如果想要计算 sync.Map 的长度,稍微有点麻烦,需要使用 Range 函数。

map 并发操作出现问题

func main() {
 demo := make(map[int]int)
 go func() {
  for j := 0; j < 1000; j++ {
   demo[j] = j
  }
 }()
 go func() {
  for j := 0; j < 1000; j++ {
   fmt.Println(demo[j])
  }
 }()
 time.Sleep(time.Second * 1)
}

执行输出:

fatal error: concurrent map read and map write

sync.Map 解决并发操作问题

func main() {
 demo := sync.Map{}
 go func() {
  for j := 0; j < 1000; j++ {
   demo.Store(j, j)
  }
 }()
 go func() {
  for j := 0; j < 1000; j++ {
   fmt.Println(demo.Load(j))
  }
 }()
 time.Sleep(time.Second * 1)
}

执行输出:

<nil> false
1 true
...
999 true

计算 map 长度

func main() {
 demo := make(map[int]int)
 for j := 0; j < 1000; j++ {
  demo[j] = j
 }
 fmt.Println("len of demo:", len(demo))
}

执行输出:

len of demo: 1000

计算 sync.Map 长度

func main() {
 demo := sync.Map{}
 
 for j := 0; j < 1000; j++ {
  demo.Store(j, j)
 }
 lens := 0
 demo.Range(func(key, value interface{}) bool {
  lens++
  return true
 })
 fmt.Println("len of demo:", lens)
}

执行输出:

len of demo: 1000

小结

  1. Load 加载 key 数据
  2. Store 更新或新增 key 数据
  3. Delete 删除 key 数据
  4. Range 遍历数据
  5. LoadOrStore 如果存在 key 数据则返回,反之则设置
  6. LoadAndDelete 如果存在 key 数据则删除

以上,希望对你能够有所帮助。

推荐阅读

目录
打赏
0
1
1
0
63
分享
相关文章
|
5月前
|
Go
go语言中遍历映射(map)
go语言中遍历映射(map)
141 8
Go 语言中的 Sync.Map 详解:并发安全的 Map 实现
`sync.Map` 是 Go 语言中用于并发安全操作的 Map 实现,适用于读多写少的场景。它通过两个底层 Map(`read` 和 `dirty`)实现读写分离,提供高效的读性能。主要方法包括 `Store`、`Load`、`Delete` 等。在大量写入时性能可能下降,需谨慎选择使用场景。
Go语言中的map数据结构是如何实现的?
Go 语言中的 `map` 是基于哈希表实现的键值对数据结构,支持快速查找、插入和删除操作。其原理涉及哈希函数、桶(Bucket)、动态扩容和哈希冲突处理等关键机制,平均时间复杂度为 O(1)。为了确保线程安全,Go 提供了 `sync.Map` 类型,通过分段锁实现并发访问的安全性。示例代码展示了如何使用自定义结构体和切片模拟 `map` 功能,以及如何使用 `sync.Map` 进行线程安全的操作。
|
4月前
|
Go
go语言for遍历映射(map)
go语言for遍历映射(map)
117 12
|
5月前
|
go语言 遍历映射(map)
go语言 遍历映射(map)
74 2
如何利用Go语言的高效性、并发支持、简洁性和跨平台性等优势,通过合理设计架构、实现负载均衡、构建容错机制、建立监控体系、优化数据存储及实施服务治理等步骤,打造稳定可靠的服务架构。
在数字化时代,构建高可靠性服务架构至关重要。本文探讨了如何利用Go语言的高效性、并发支持、简洁性和跨平台性等优势,通过合理设计架构、实现负载均衡、构建容错机制、建立监控体系、优化数据存储及实施服务治理等步骤,打造稳定可靠的服务架构。
119 1
探索Go语言中的并发模式:goroutine与channel
在本文中,我们将深入探讨Go语言中的核心并发特性——goroutine和channel。不同于传统的并发模型,Go语言的并发机制以其简洁性和高效性著称。本文将通过实际代码示例,展示如何利用goroutine实现轻量级的并发执行,以及如何通过channel安全地在goroutine之间传递数据。摘要部分将概述这些概念,并提示读者本文将提供哪些具体的技术洞见。
Go语言的并发特性
【10月更文挑战第26天】Go语言的并发特性
52 1
|
28天前
使用 entrySet 遍历 Map 类集合 KV
使用 entrySet 遍历 Map 类集合 KV
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用
该文章详细介绍了ES6中Set和Map数据结构的特性和使用方法,并探讨了它们在前端开发中的具体应用,包括如何利用这些数据结构来解决常见的编程问题。
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用

热门文章

最新文章