互斥锁
- sync.mutex
- 获取到锁的任务,阻塞其他任务
- 意味着同一时间只有一个go才能持有锁
- 互斥锁举例 ```go package main
import ( “log” “sync” “time” )
var HcMutex sync.Mutex
func runMutex(id int) { log.Printf(“[任务id:%d][尝试获取锁]”, id) HcMutex.Lock() log.Printf(“[任务id:%d][获取到了锁][开始干活:睡眠10秒]”, id) time.Sleep(10 * time.Second) HcMutex.Unlock() log.Printf(“[任务id:%d][干完活了 释放锁]”, id) }
func runHcLock() { go runMutex(1) go runMutex(2) go runMutex(3) }
func main() { // 执行互斥锁 效果任务 runHcLock()
time.Sleep(600 * time.Second) //演示使用,目的是不让主线程延迟退出
}
<a name="kwcAP"></a>## **读写锁**- sync.rwmutex- 写锁阻塞所有锁(所有读锁和写锁) ,目的是修改时其他人不要读取,也不要修改- 读锁阻塞写锁 ,读锁可以同时施加多个 。目的 不要让修改数据影响我的读取结果- 同时多个读任务, 可以施加多个读锁,阻塞写锁- 同时多个写任务 ,只可以施加一个写锁,阻塞其他所有锁 ,退化成互斥锁- 读写混合:若有写锁,等待释放后能施加 读或写- 读写混合:若有读锁,只能再施加读锁,阻塞写锁```gopackage mainimport ("log""sync""time")var HcMutex sync.Mutexvar rwMutex sync.RWMutexfunc runMutex(id int) {log.Printf("[任务id:%d][尝试获取锁]", id)HcMutex.Lock()log.Printf("[任务id:%d][获取到了锁][开始干活:睡眠10秒]", id)time.Sleep(10 * time.Second)HcMutex.Unlock()log.Printf("[任务id:%d][干完活了 释放锁]", id)}func runHcLock() {go runMutex(1)go runMutex(2)go runMutex(3)}func runReadLock(id int) {log.Printf("[读任务:%d][进入读方法等待获取读锁]", id)rwMutex.RLock()log.Printf("[读任务:%d][获取到了读锁][干活:睡眠10秒]", id)time.Sleep(10 * time.Second)rwMutex.RUnlock()log.Printf("[读任务:%d][完成读任务,释放读锁]",id)}func runWriteLock(id int) {log.Printf("[写任务:%d][进入写方法等待获取写锁]", id)rwMutex.Lock()log.Printf("[写任务:%d][获取到了写锁][干活:睡眠10秒]", id)time.Sleep(10 * time.Second)rwMutex.Unlock()log.Printf("[写任务:%d][完成写任务,释放写锁]",id)}func allWriteWorks() {for i := 1; i < 6; i++ {go runWriteLock(i)}}func allReadWorks() {for i := 1; i < 6; i++ {go runReadLock(i)}}func writeFirst() {go runWriteLock(1)time.Sleep(1 * time.Second)go runReadLock(1)go runReadLock(2)go runReadLock(3)go runReadLock(4)go runReadLock(5)}func readFirst() {go runReadLock(1)go runReadLock(2)go runReadLock(3)go runReadLock(4)go runReadLock(5)time.Sleep(1 * time.Second)go runWriteLock(1)}func main() {// 执行互斥锁 效果任务//runHcLock()// 同时多个写锁任务,说明如果 并非使用 读写锁的写锁任务时,退化成了互斥锁//allWriteWorks()// 同时并发 读锁任务, 说明读写锁的读锁 是可以同时施加多个读锁的//allReadWorks()// 先启动写锁任务,后并非5个读锁任务,当有写锁时,读锁施加不了,写锁释放完,读锁可以施加多个//writeFirst()// 并发5个读锁任务,启动一个写锁任务, 当有读锁时,阻塞写锁readFirst()time.Sleep(6000 * time.Second)}
