由于互斥锁对于共享资源形成了独占,所以在代码上也就达到了一种严格的串行化执行
优点:可以控制住代码的执行步骤 缺点:让高并发的程序性能打了折扣
在实际开发中,根据应用场景会把所分为读锁和写锁
读锁:会阻止别人的写,不会阻止别人的写
写锁:会阻止别人的写,也会阻止别人的读
如果把互斥锁换成适合应用场景的读写锁,那么一定会因为读锁达到一定数量级而产生性能提升
读写锁,从源代码的结构体里看,就可以发现,它是在互斥锁的基础上加计数器实现的
所以:在单独拿到一把锁的效率上来看,一定是互斥锁获取更快
package main
import (
"fmt"
"sync"
"time"
)
var (
x int64
wg sync.WaitGroup
lock sync.Mutex
rwlock sync.RWMutex
)
func write() {
// lock.Lock() // 加互斥锁
rwlock.Lock() // 加写锁,写锁会阻止别人的写,也会阻止别人的读
x = x + 1
time.Sleep(10 * time.Millisecond) // 假设写操作耗时10毫秒
rwlock.Unlock() // 解写锁
// lock.Unlock() // 解互斥锁
wg.Done()
}
func read() {
// lock.Lock() // 加互斥锁
rwlock.RLock() // 加读锁,读锁会阻止别人的写,不会阻止别人的写
time.Sleep(time.Millisecond) // 假设读操作耗时1毫秒
rwlock.RUnlock() // 解读锁
// lock.Unlock() // 解互斥锁
wg.Done()
}
func main() {
start := time.Now()
for i := 0; i < 10; i++ {
wg.Add(1)
go write()
}
for i := 0; i < 1000; i++ {
wg.Add(1)
go read()
}
wg.Wait()
end := time.Now()
fmt.Println(end.Sub(start))
}
//明显对比出来:当读锁需求明显多于写锁需求时,读写锁的优势会在数量级上优于互斥锁
//使用互斥锁耗时:
//1.7243907s
//使用读写互斥锁:
//176.6876ms