读写锁,RWMuex
常用的有四个方法 Lock(), Rlock(), Unlock(),RUnlock(),分别是加写锁,加读锁,释放写锁以及释放读锁
对于写锁来说,会阻塞其他的写锁和读锁
对于读锁来说,不会阻塞读锁(可以同时有多个读锁存在),但是会阻塞写锁
同时因为读锁可以有多个,所以当存在一个读和写的goroutine时,写的协程只能等全部的读锁被释放时才能获取。
应用场景就是在一个系统中,大部分时间是读的请求大于写的请求。
所以读是可以并发的,但是显然写和读、写和写之间只能是串行,不能同时进行。
例如:
package main
import (
"fmt"
"sync"
"time"
)
var (
rwlock sync.RWMutex
wg sync.WaitGroup
)
func main() {
wg.Add(6)
go func() {
defer wg.Done()
time.Sleep(time.Second) // 为了让读锁先被获取
rwlock.Lock()
defer rwlock.Unlock()
fmt.Println("获取到写锁")
time.Sleep(3 * time.Second)
}()
for range 5 {
go func() {
defer wg.Done()
for {
rwlock.RLock()
fmt.Println("获取到读锁")
time.Sleep(500 * time.Millisecond)
rwlock.RUnlock()
}
}()
}
wg.Wait()
}
在这个例子中一共是启了6个goroutine,其中一个负责写,另外五个负责读,在读的goroutine中有一个for循环不断获取读锁,在写的goroutine中当获取到写锁之后休眠3秒,让效果更直观。