sync.Mutex
1.sync.Mutex 为互斥锁,适用于读写不确定,并且只有一个读或者写的场景。
2.在一个 goroutine 获得互斥锁后,其他 goroutine 只能等待释放该互斥锁。
3.在同一个 goroutine 中的 sync.Mutex 解锁之前再次进行加锁,会导致死锁。
4.Lock() 加锁后不能再继续对其加锁,会阻塞直到 Unlock() 解锁后才能加锁。
5.在没有锁的情况下解锁会导致 panic 错误。
package main import ( "fmt" "sync" "time" ) func main() { var ( lock sync.Mutex m = make(map[int]int) ) for i := 0; i < 10; i++ { i := i go func() { lock.Lock() m[i] = i lock.Unlock() }() } time.Sleep(time.Second) for k, v := range m { fmt.Println(k, v) } }
sync.RWMutex
1.sync.RWMutex 是单写多读锁,该锁可以加多个读锁或者一个写锁,适用于读多写少的场景。
2.读锁占用的情况下会阻止写,不会阻止读,多个 goroutine 可以同时获取读锁。
3.写锁会阻止其他 goroutine (无论读和写)进来,整个锁由该 goroutine 独占。
4.RLock() 读锁可以加多个,如果存在写锁,则无法加读锁,否则会导致死锁。
5.Lock() 写锁只能加一个,且只能在没有读锁时添加,否则会导致死锁,写锁未解锁前添加会阻塞。
6.RUnlock() 只能撤销单次 RLock() 调用,对于其他同时存在的读锁没有作用。
7.Unlock() 只能撤销 Lock() 调用,不可用于解除读锁。
8.在没有锁的情况下解锁会导致 panic 错误。
package main import ( "fmt" "sync" "time" ) func main() { var lock sync.RWMutex // var lock sync.Mutex lock.Lock() // 再次加写锁会阻塞到写锁解锁 go func() { lock.Lock() fmt.Println("hello") lock.Unlock() }() time.Sleep(time.Second) lock.Unlock() time.Sleep(time.Second) }
本文标题:golang 中的两种锁
版权声明:本文使用「署名-非商业性使用-相同方式共享」创作共享协议,转载或使用请遵守署名协议。