Mutex互斥锁(排他锁):
同一时刻一段代码只能被一个线程运行,在Lock()和Unlock()之间的代码段称为资源的临界区(critical section),是线程安全的,任何一个时间点都只能有一个goroutine执行这段区间的代码。
方法:Lock(加锁)、Unlock(解锁)
但Mutex在大量并发的情况下,会造成锁等待,对性能的影响比较大。如果某个读操作的协程加了锁,其他的协程没必要处于等待状态,可以并发地访问共享变量,这样能让读操作并行,提高读性能。
如果我们可以明确区分reader和writer的协程场景,且是大量的并发读、少量的并发写,有强烈的性能需要,我们就可以考虑使用读写锁RWMutex替换Mutex
读写锁:
方法:Lock(加锁)、Unlock(解锁)这种锁在某一时刻能由任意数量的reader持有,或者被一个wrtier持有
使用主要遵循以下规则 :
读写锁的读锁可以重入,在已经有读锁的情况下,可以任意加读锁。
在读锁没有全部解锁的情况下,写操作会阻塞直到所有读锁解锁。
写锁定的情况下,其他协程的读写都会被阻塞,直到写锁解锁。
Go语言的读写锁方法主要有下面这种:
Lock/Unlock:针对写操作
不管锁是被reader还是writer持有,这个Lock方法会一直阻塞,Unlock用来释放锁的方法
RLock/RUnlock:针对读操作
当锁被reader所有的时候,RLock会直接返回,当锁已经被writer所有,RLock会一直阻塞,直到能获取锁,否则就直接返回,RUnlock用来释放锁的方法
注意:写独占,读共享,写锁优先级高