十三. Go學習:鎖機制
阿新 • • 發佈:2020-12-27
技術標籤:Golang學習總結golang
執行緒同步時,可能會有多個執行緒需要使用這個資源,為了避免資源競爭,我們需要鎖機制。
1. import("sync")
2. 互斥鎖,var mu sync.Mutex
2. 讀寫所, var mu sync.RWMutex
互斥鎖
package main import ( "fmt" "math/rand" "sync" "sync/atomic" "time" ) var lock sync.Mutex func testMap() { var a map[int]int a = make(map[int]int, 5) a[8] = 10 a[3] = 10 a[2] = 10 a[1] = 10 a[18] = 10 //互斥鎖,一次只能進一個 for i := 0; i < 2; i++ { go func(b map[int]int) { lock.Lock() b[8] = rand.Intn(100) lock.Unlock() }(a) } lock.Lock() fmt.Println(a) lock.Unlock() } func main(){ testMap() }
讀寫鎖
適合讀多寫少的情景。
程式碼範例如下。結果顯示共計數81601次,而如果用互斥鎖僅僅能計數814次。
package main import ( "fmt" "math/rand" "sync" "sync/atomic" //原子操作,用於gorounte計數 "time" ) var lock sync.Mutex var rwLock sync.RWMutex func testRWLock() { var a map[int]int a = make(map[int]int, 5) var count int32 //讀寫鎖,讀者只對共享資源進行讀訪問,寫著則需要對共享資源進行寫操作 a[8] = 10 a[3] = 10 a[2] = 10 a[1] = 10 a[18] = 10 for i := 0; i < 2; i++ { go func(b map[int]int) { rwLock.Lock() b[8] = rand.Intn(100) rwLock.Unlock() }(a) } go func(b map[int]int) { for { //lock.Lock() rwLock.RLock() time.Sleep(time.Millisecond * 3) rwLock.RUnlock() //lock.Unlock() atomic.AddInt32(&count, 1) //計數讀了多少次 } }(a) time.Sleep(time.Second * 3) fmt.Println(atomic.LoadInt32(&count)) } func main() { // testMap() testRWLock() }