读写锁

最后更新于:2022-04-02 04:46:58

2、读写锁 (用于读取多,写入少的操作应用) ~~~ type RWMutex func (rw *RWMutex) Lock() func (rw *RWMutex) RLock() func (rw *RWMutex) RLocker() Locker func (rw *RWMutex) RUnlock() func (rw *RWMutex) Unlock() ~~~ RWMutex是一个读写锁,该锁可以加多个读锁或者一个写锁,其经常用于读次数远远多于写次数的场景. func (rw *RWMutex) Lock()  写锁,如果在添加写锁之前已经有其他的读锁和写锁,则lock就会阻塞直到该锁可用,为确保该锁最终可用,已阻塞的 Lock 调用会从获得的锁中排除新的读取器,即写锁权限高于读锁,有写锁时优先进行写锁定 func (rw *RWMutex) Unlock() 写锁解锁,如果没有进行写锁定,则就会引起一个运行时错误 func (rw *RWMutex) RLock() 读锁,当有写锁时,无法加载读锁,当只有读锁或者没有锁时,可以加载读锁,读锁可以加载多个,所以适用于"读多写少"的场景 func (rw *RWMutex)RUnlock() 读锁解锁,RUnlock 撤销单次RLock 调用,它对于其它同时存在的读取器则没有效果。若 rw 并没有为读取而锁定,调用 RUnlock 就会引发一个运行时错误(注:这种说法在go1.3版本中是不对的,例如下面这个例子)。 读写锁的写锁只能锁定一次,解锁前不能多次锁定,读锁可以多次,但读解锁次数最多只能比读锁次数多一次,一般情况下我们不建议读解锁次数多余读锁次数。 读多写少的情况,用读写锁, 携程同时在操作读。 ~~~ package main import ( "fmt" "math/rand" "sync" "time" ) //读写锁 var rwLock sync.RWMutex func testRWLock() { var a map[int]int a = make(map[int]int, 5) a[8] = 10 a[3] = 10 a[2] = 10 a[1] = 10 a[18] = 10 for i := 0; i < 2; i++ { go func(b map[int]int) { rwLock.Lock() b[8] = rand.Intn(100) rwLock.Unlock() }(a) } for i := 0; i < 10; i++ { go func(b map[int]int) { rwLock.RLock() //读锁 fmt.Println(a) rwLock.RUnlock() }(a) } time.Sleep(time.Second * 2) } func main() { testRWLock() //读多写少的时候,用读写锁 } ~~~ 输出结果: ~~~ map[3:10 2:10 1:10 18:10 8:81] map[8:87 3:10 2:10 1:10 18:10] map[2:10 1:10 18:10 8:87 3:10] map[2:10 1:10 18:10 8:87 3:10] map[8:87 3:10 2:10 1:10 18:10] map[8:87 3:10 2:10 1:10 18:10] map[2:10 1:10 18:10 8:87 3:10] map[8:87 3:10 2:10 1:10 18:10] map[1:10 18:10 8:87 3:10 2:10] map[8:87 3:10 2:10 1:10 18:10] ~~~
';