0Pricing
Go Academy · 课时

sync.Once 与 sync.Map

一次性初始化与并发映射

sync.Once 与 sync.Map 是 CoddyKit 上的免费 Go Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Go Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Go Academy 课程共包含 4 节课。

sync.Once

sync.Once 保证某个函数只运行一次,无论有多少个协程并发调用它。典型用例是单例的延迟初始化。

Once.Do

只有对 Do 的第一次调用会执行该函数;后续调用即使来自不同协程,也不会执行任何操作。

var once sync.Once
var db *Database

func getDB() *Database {
    once.Do(func() { db = openDB() })
    return db
}

Once 不会重置

sync.Once 一旦执行过,就无法重置。如果需要可重置的一次性执行,请使用原子操作或互斥锁手动管理状态。

Once 的恐慌行为

如果传递给 Do 的函数触发恐慌,Do 会被视为已完成,后续调用不会执行任何操作。该恐慌会传播给第一个调用者。

sync.Map 概览

sync.Map 是一种无需外部加锁的并发映射。它针对两种模式进行了优化:(1)只写入一次、读取多次;(2)每个协程使用互不相交的键集合。

sync.Map 方法

主要方法:Store、Load、LoadOrStore、删除、Range。没有泛型类型参数——键和值都是 interface{}。

var m sync.Map
m.Store("key", 42)
v, ok := m.Load("key")
if ok { fmt.Println(v.(int)) }

LoadOrStore

LoadOrStore 在键存在时返回已有值,否则存储并返回新值。布尔值表示值是已加载(true)还是已存储(false)。

actual, loaded := m.LoadOrStore("key", "default")
if loaded { fmt.Println("existing:", actual) }

Range

Range 会遍历所有键值对,并为每一对调用该函数。返回 false 可停止遍历。

m.Range(func(k, v any) bool {
    fmt.Println(k, v)
    return true // continue
})

何时使用 sync.Map

大多数情况下,优先使用带 Mutex 的普通映射——它更简单,而且通常更快。当性能分析显示存在竞争,或访问模式符合其优化目标时,再使用 sync.Map。

LoadAndDelete

LoadAndDelete 会以原子方式加载值并删除键,同时返回之前的值以及该键是否存在。

v, loaded := m.LoadAndDelete("key")
if loaded { fmt.Println("deleted:", v) }

sync.Map 不是泛型的

存储在 sync.Map 中的值是 any。请将 sync.Map 封装在带类型的方法的类型安全结构体中,以避免在代码库中到处进行类型断言。

快速检查

sync.Once 保证什么?

回顾:sync.Once 与 sync.Map

要点:

  • sync.Once:让函数恰好运行一次;且不可逆
  • sync.Map:针对读操作密集型或键互不相交模式优化的并发映射
  • 为保证安全性,请在 sync.Map 外封装带类型的包装器

常见问题解答

「sync.Once 与 sync.Map」课时是免费的吗?

是的 — 「sync.Once 与 sync.Map」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Go Academy 课程的其余内容,请升级到 CoddyKit PRO。 Go Academy 课程共包含 4 节课。

「sync.Once 与 sync.Map」这节课中我会学到什么?

一次性初始化与并发映射 你通过在浏览器中直接运行的动手代码来练习 Go Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Go Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Go Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「sync.Once 与 sync.Map」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Go Academy 课中编写并运行代码吗?

能。每节 Go Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. sync.Mutex 与 sync.RWMutex
  2. sync.WaitGroup
  3. sync.Once 与 sync.Map
  4. 竞态检测器与安全模式
← 返回 Go Academy