推荐答案
在 Go 语言的 sync 包中,除了 sync.Once 和 sync.Cond 之外,还有以下几种常用的同步原语:
- sync.Mutex:互斥锁,用于保护共享资源,防止多个 goroutine 同时访问。
- sync.RWMutex:读写锁,允许多个读操作同时进行,但写操作是独占的。
- sync.WaitGroup:用于等待一组 goroutine 完成。
- sync.Map:并发安全的 map,适用于读多写少的场景。
- sync.Pool:对象池,用于缓存和复用临时对象,减少内存分配的开销。
本题详细解读
sync.Mutex
sync.Mutex 是 Go 语言中最基本的同步原语之一。它提供了两个方法:Lock() 和 Unlock()。当一个 goroutine 调用 Lock() 时,如果锁已经被其他 goroutine 持有,那么当前 goroutine 会被阻塞,直到锁被释放。Unlock() 方法用于释放锁。
var mu sync.Mutex
var counter int
func increment() {
mu.Lock()
counter++
mu.Unlock()
}sync.RWMutex
sync.RWMutex 是读写锁,它允许多个读操作同时进行,但写操作是独占的。它提供了 RLock() 和 RUnlock() 方法用于读锁,Lock() 和 Unlock() 方法用于写锁。
// www.javascriptcn.com code example
var rwmu sync.RWMutex
var data map[string]string
func readData(key string) string {
rwmu.RLock()
defer rwmu.RUnlock()
return data[key]
}
func writeData(key, value string) {
rwmu.Lock()
defer rwmu.Unlock()
data[key] = value
}sync.WaitGroup
sync.WaitGroup 用于等待一组 goroutine 完成。它提供了 Add()、Done() 和 Wait() 方法。Add() 方法用于增加等待的 goroutine 数量,Done() 方法用于减少等待的 goroutine 数量,Wait() 方法用于阻塞直到所有 goroutine 完成。
// www.javascriptcn.com code example
var wg sync.WaitGroup
func worker() {
defer wg.Done()
// 执行任务
}
func main() {
wg.Add(2)
go worker()
go worker()
wg.Wait()
}sync.Map
sync.Map 是一个并发安全的 map,适用于读多写少的场景。它提供了 Load()、Store()、Delete() 等方法。
// www.javascriptcn.com code example
var m sync.Map
func main() {
m.Store("key", "value")
value, ok := m.Load("key")
if ok {
fmt.Println(value)
}
}sync.Pool
sync.Pool 是对象池,用于缓存和复用临时对象,减少内存分配的开销。它提供了 Get() 和 Put() 方法。
// www.javascriptcn.com code example
var pool = sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
}
func main() {
buf := pool.Get().(*bytes.Buffer)
buf.Reset()
buf.WriteString("hello")
pool.Put(buf)
}