golang主要有两种锁:互斥锁和读写锁
互斥锁 Mutex 用于提供一种加锁机制(Locking Mechanism),保证同一时刻只有一个goroutine在临界区运行
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var mutex sync.Mutex
x := 0
go func() {
mutex.Lock()
x = x + 1
mutex.Unlock()
}()
time.Sleep(time.Second)
fmt.Println(x)
}
读写锁RWMutex:读写锁实际是一种特殊的自旋锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作。这种锁相对于自旋锁而言,能提高并发性,因为在多处理器系统中,它允许同时有多个读者来访问共享资源,最大可能的读者数为实际的逻辑CPU数。写者是排他性的,一个读写锁同时只能有一个写者或多个读者(与CPU数相关),但不能同时既有读者又有写者。
总的来说,就是写的时候不允许读和多个写,读的时候不允许写但是允许多个读,读和写不能同时进行。
Lock方法将rw锁定为写入状态,禁止其他线程读取或者写入。
Unlock方法解除rw的写入锁状态,如果m未加写入锁会导致运行时错误。
RLock方法将rw锁定为读取状态,禁止其他线程写入,但不禁止读取。
RUnlock方法解除rw的读取锁状态,如果m未加读取锁会导致运行时错误
func read() {
rwmutex.RLock()
fmt.Println("read i", i)
rwmutex.RUnlock()
}
func write() {
rwmutex.Lock()
rand.Seed(time.Now().Unix())
i = rand.Intn(10)
fmt.Println("write i", i)
rwmutex.Unlock()
}
func main() {
go func() {
write()
read()
time.Sleep(time.Second)
write()
read()
}()
time.Sleep(2 * time.Second)
}