go中普通map和sync.map的区别小结

 更新时间:2025年09月30日 09:16:03   作者:{⌐■_■}  
本文主要介绍了go中普通map和sync.map的区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

1. 普通map的特点

Go 内置的 map非并发安全的:

  • 单协程里读写没问题;
  • 多协程同时写会触发 fatal error: concurrent map writes
  • 多协程并发读写需要自己加锁(如 sync.RWMutex)。

源码层面(runtime/map.go):

  • map 内部通过 hmap 结构体存储桶(buckets)管理数据;
  • 设计目标是高性能单线程
  • 并没有加锁逻辑。

2.sync.Map的特点

Go 在 1.9+ 引入了 sync.Map,为高并发场景做了专门优化。
特点:

  • 并发安全,内部已经封装了锁;
  • 针对读多写少的场景做了特别优化(类似“读写分离”)。

源码层面(sync/map.go):

type Map struct {
    mu Mutex               // 写操作用的锁
    read atomic.Value      // 存储只读部分,原子读
    dirty map[any]*entry   // 可写部分,写时更新
    misses int             // 记录从 read 读取失败的次数
}

核心机制:

  • 双 map 设计

    • read(只读,atomic.Value):无锁读,性能高;
    • dirty(写缓冲,受锁保护):存储新增/修改的数据;
  • 写时迁移策略:当 read 中 miss 次数过多,会把 dirty 提升为 read

  • 保证读快写慢的同时,整体高并发安全。

通过readdirty分别存储读写状态,以空间换时间的策略,去减少锁冲突。

3. 举个对比例子

// 普通 map + 锁
var m = make(map[string]int)
var mu sync.RWMutex

func safeWrite(k string, v int) {
    mu.Lock()
    defer mu.Unlock()
    m[k] = v
}

func safeRead(k string) (int, bool) {
    mu.RLock()
    defer mu.RUnlock()
    v, ok := m[k]
    return v, ok
}

sync.Map 相比:

  • 普通 map+RWMutex写性能更好,适合频繁写
  • sync.Map读性能更好,适合读多写少

4. 面试回答

普通 map 是非并发安全的,需要开发者手动用 sync.RWMutex 保证线程安全。
sync.Map 内部采用 读写分离(read + dirty) 的双 map 设计,读操作可以无锁原子读,写操作用锁保护,并在一定 miss 次数后把 dirty 提升为 read
适用场景不同:

  • sync.Map:读多写少,典型场景如缓存、配置表;
  • map+RWMutex:写多的场景更优。

到此这篇关于go中普通map和sync.map的区别小结的文章就介绍到这了,更多相关go中普通map和sync.map内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Golang 经典校验库 validator 用法解析

    Golang 经典校验库 validator 用法解析

    这篇文章主要为大家介绍了Golang 经典校验库 validator 用法解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • Go+Gin实现安全多文件上传功能

    Go+Gin实现安全多文件上传功能

    这篇文章主要为大家详细介绍了Go如何利用Gin框架实现安全多文件上传功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-04-04
  • 详解prometheus监控golang服务实践记录

    详解prometheus监控golang服务实践记录

    这篇文章主要介绍了详解prometheus监控golang服务实践记录,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • Go语言实现新春祝福二维码的生成

    Go语言实现新春祝福二维码的生成

    二维码现在是随处度可以看到,买东西,支付,添加好友只要你扫一扫就能完成整个工作,简单且方便。所以利用这个新春佳节做一个带着新春祝福的二维码吧
    2023-02-02
  • 基于golang的轻量级工作流框架Fastflow

    基于golang的轻量级工作流框架Fastflow

    这篇文章主要介绍了基于golang的轻量级工作流框架Fastflow,fastflow 执行任务的过程会涉及到几个概念:Dag, Task, Action, DagInstance,本文给大家分享完整流程,需要的朋友可以参考下
    2022-05-05
  • 使用Go语言实现的WebDAV内存文件系统

    使用Go语言实现的WebDAV内存文件系统

    这篇文章主要为大家详细介绍了如何使用Go语言实现的WebDAV内存文件系统,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-11-11
  • gin解析json格式的数据出错的处理方案

    gin解析json格式的数据出错的处理方案

    这篇文章主要介绍了gin解析json格式的数据出错的处理方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • 一文详解Python如何处理无法解码文件名

    一文详解Python如何处理无法解码文件名

    在跨平台文件处理,国际化应用或系统管理工具开发中,文件名无法正确解码是文件名无法正确解码,本文将深入探讨Python中处理无法解码文件名的方法,大家可以根据需要进行选择
    2025-09-09
  • 深入了解Go语言中context的用法

    深入了解Go语言中context的用法

    这篇文章主要为大家详细介绍了Go语言中context用法的相关知识,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-07-07
  • Go语言获取本机逻辑CPU数量的方法

    Go语言获取本机逻辑CPU数量的方法

    这篇文章主要介绍了Go语言获取本机逻辑CPU数量的方法,实例分析了runtime库的操作技巧,需要的朋友可以参考下
    2015-03-03

最新评论