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内存对齐的概念及案例详解

    golang内存对齐的概念及案例详解

    为保证程序顺利高效的运行,编译器会把各种类型的数据安排到合适的地址,并占用合适的长度,这就是内存对齐。本文重点给大家介绍golang内存对齐的概念及案例详解,感兴趣的朋友一起看看吧
    2022-02-02
  • go nil处理如何正确返回nil的error

    go nil处理如何正确返回nil的error

    这篇文章主要为大家介绍了go中的nil处理,如何正确返回nil的error实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • go判断文件夹是否存在并创建的实例

    go判断文件夹是否存在并创建的实例

    这篇文章主要介绍了go判断文件夹是否存在,并创建的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • golang json性能分析详解

    golang json性能分析详解

    json格式可以算我们日常最常用的序列化格式之一了,Go语言作为一个由Google开发,号称互联网的C语言的语言,自然也对JSON格式支持很好。下面这篇文章主要给大家详细分析介绍了golang json性能的相关资料,需要的朋友可以参考下。
    2018-02-02
  • go内存缓存如何new一个bigcache对象示例详解

    go内存缓存如何new一个bigcache对象示例详解

    这篇文章主要为大家介绍了go内存缓存如何new一个bigcache对象示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • GO 之运算符号的具体使用

    GO 之运算符号的具体使用

    这篇文章主要介绍了GO运算符号的具体使用,包括算术、一元、关系、逻辑、位运算及赋值运算符,感兴趣的可以了解一下
    2025-06-06
  • go中如何获取本机ip地址

    go中如何获取本机ip地址

    这篇文章主要介绍了go中如何获取本机ip地址问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Go调度器学习之协作与抢占详解

    Go调度器学习之协作与抢占详解

    如果某个G执行时间过长,其他的G如何才能被正常调度,这就引出了接下来的话题:协作与抢占。本文将通过一些示例为大家详细讲讲调度器中协作与抢占的相关知识,需要的可以参考一下
    2023-04-04
  • go语言题解LeetCode1160拼写单词示例详解

    go语言题解LeetCode1160拼写单词示例详解

    这篇文章主要为大家介绍了go语言题解LeetCode1160拼写单词示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • Go语言fmt.Sprintf格式化输出的语法与实例

    Go语言fmt.Sprintf格式化输出的语法与实例

    Go 可以使用 fmt.Sprintf 来格式化字符串,下面这篇文章主要给大家介绍了关于Go语言fmt.Sprintf格式化输出的语法与实例,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07

最新评论