键入go doc sync
你可以获得以下文档内容:
1 | package sync // import "sync" |
我们针对每个类型进行分析吧(顺序不按照上面给出)。
sync.Locker
这个接口定义了锁结构必须实现的方法,也就是加锁和解锁,没有什么特别值得注意的。
1 | type Locker interface { |
后面我们将看到很多原语都实现了这个接口。
sync.Mutex / sync.RWMutex
顾名思义,这两个原语实现了互斥锁/读写互斥锁。
sync.Once
该原语能够确保某个函数只被执行一次。
sync.WaitGroup
该源于用于在一个 goroutine 中等待其他一组 goroutine 执行完毕。
sync.Pool
这是一个并发池,用来安全地保存一组对象。当我们必须重用共享的和长期存在的对象(例如,数据库连接)时,或者需要优化内存分配时(使用sync.Pool
可以防止GC后再分配)。
sync.Map
这是一个并发安全的map
。当我们对map
有频繁的读取和不频繁的写入,或者多个 goroutine 读取/写入/覆盖不相交的 key
时,我们使用 sync.Map
而不是普通的map
配合sync.Mutex
。
注:Any race is a bug. 即使多个 goroutine 写入不相交map键,也会导致程序崩溃(
fatal error: concurrent map read and map write
),因为map的底层实现逻辑。关于底层逻辑之后再谈。
sync.Cond
很不常用地,这个原语用于发出一对一信号或广播信号。创建这个原语需要一个sync.Locker
作为参数。