Golang中的sync包实现了两种锁:互斥锁(Mutex)和读写锁(RWMutex)。
互斥锁的一个经典案例是对切片进行并发安全的操作,代码如下:
package main
import (
"fmt"
"sync"
)
var mu sync.Mutex
var slice []int
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
for j := 0; j < 100; j++ {
mu.Lock()
slice = Append(slice, j)
mu.Unlock()
}
wg.Done()
}()
}
wg.Wait()
fmt.Println(len(slice))
}
首先定义了一个长度为0的slice,并发地对其进行了1000次append操作。
看一个代码示例:
package main
import (
"log"
"sync"
)
var mu sync.RWMutex
var m map[string]string
func main() {
m = make(map[string]string)
mu.Lock()
m["a"] = "A"
mu.Unlock()
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func(i int) {
mu.RLock()
log.Println(m["a"]) // 并发读
mu.RUnlock()
wg.Done()
}(i)
}
wg.Wait()
}
首先定义了一个map,然后对其进行了一次写操作和10次并发读操作。在并发读的时候,使用读锁来支持并发访问。
本文讲解了互斥锁和读写锁的特点,两种锁都可以用于协调多个并发访问共享资源的同步机制。可以看出互斥锁适用于读写不确定,并且只有一个读或者写的场景;读写锁适用于读多写少的场景,可以有更高的性能。需要注意的是尽量避免在锁的范围内进行耗时较长的操作,以免影响性能。