首先通过下面的例子了解下什么是并发安全:
猜猜结果是什么? 40000? 有可能,但不一定:
num并不一定等于40000,这是由于两个goroutine在读写num变量时存在数据竞争的原因,所以最终结果不一定与期待值一致
怎么解决数据竞争呢?
可以这样,当A goroutine读写变量时,锁住变量的读写权限,使得其他goroutine不能去读写即可
sync包里的两把锁就是为了解决并发安全而存在的,下面一一介绍
mutex是mutual exclusion的缩写,是互斥的意思,一般称其为互斥锁:
重点:
未初始化的sync.Mutex就已经是一个未上锁的互斥锁(零值即可用)
sync.Mutex和sync.WaitGroup一样,一旦开始使用,不能够再次复制
每次读写num变量时,加锁,读写完后,解锁:
这样每次执行的结果都是一致的:
还有一个要注意的点是,尽可能的去使用defer sync.Unlock,否则有可能出现panic时,没法执行Unlock
所以再改动下代码:
rwmutex是reader/writer mutual exclusion的缩写,它表示一个读写互斥锁
读写包含两个操作,一个是读取,一个是修改。
sync.Mutex会将读写一起锁住,而sync.RWMutex允许只锁写操作或只锁读操作,而且一个goroutine的读操作不会影响另一个goroutine的读操作
所以边读边写的情况下,RWMutex比Mutex更高效
写锁操作方法:
读锁操作方法:
下面是例子: