###互斥鎖golang
其中Mutex爲互斥鎖,Lock()加鎖,Unlock()解鎖,使用Lock()加鎖後,便不能再次對其進行加鎖,直到利用Unlock()解鎖對其解鎖後,才能再次加鎖.適用於讀寫不肯定場景,即讀寫次數沒有明顯的區別,而且只容許只有一個讀或者寫的場景,因此該鎖葉叫作全局鎖.編程
package main import ( "fmt" "sync" "errors" ) type MyMap struct { mp map[string]int mutex *sync.Mutex } func (this *MyMap) Get(key string) (int, error) { this.mutex.Lock() i, ok := this.mp[key] this.mutex.Unlock() if !ok { return i, errors.New("不存在") } return i, nil } func (this *MyMap) Set(key string, v int) { this.mutex.Lock() defer this.mutex.Unlock() this.mp[key] = v } func (this *MyMap) Display() { this.mutex.Lock() defer this.mutex.Unlock() for k,v := range this.mp { fmt.Println(k, "=", v) } } func SetValue(m *MyMap) { var a rune a = 'a' for i:=0; i<10; i++ { m.Set(string(a+rune(i)),i) } } func main() { m := &MyMap{mp:make(map[string]int), mutex:new(sync.Mutex)} go SetValue(m) /*啓動一個線程向 map 寫入值*/ go m.Display() /*啓動一個線程讀取 map 的值*/ var str string /*這裏主要是等待線程結束*/ fmt.Scan(&str) }
###讀寫鎖併發
讀寫鎖便是針對於讀寫操做的互斥鎖。它與普通的互斥鎖最大的不一樣就是,它能夠分別針對讀操做和寫操做進行鎖定和解鎖操做。讀寫鎖遵循的訪問控制規則與互斥鎖有所不一樣。this
在讀寫鎖管轄的範圍內,它容許任意個讀操做的同時進行。可是,在同一時刻,它只容許有一個寫操做在進行。而且,在某一個寫操做被進行的過程當中,讀操做的進行也是不被容許的。.net
也就是說,讀寫鎖控制下的多個寫操做之間都是互斥的,而且寫操做與讀操做之間也都是互斥的。可是,多個讀操做之間卻不存在互斥關係。線程
package main import ( "fmt" "sync" "errors" ) type MyMap struct { mp map[string]int mutex *sync.RWMutex } func (this *MyMap) Get(key string) (int, error) { this.mutex.RLock() i, ok := this.mp[key] this.mutex.RUnlock() if !ok { return i, errors.New("不存在") } return i, nil } func (this *MyMap) Set(key string, v int) { this.mutex.RLock() defer this.mutex.RUnlock() this.mp[key] = v } func (this *MyMap) Display() { this.mutex.RLock() defer this.mutex.RUnlock() for k,v := range this.mp { fmt.Println(k, "=", v) } } func SetValue(m *MyMap) { var a rune a = 'a' for i:=0; i<10; i++ { m.Set(string(a+rune(i)),i) } } func main() { m := &MyMap{mp:make(map[string]int), mutex:new(sync.RWMutex)} go SetValue(m) /*啓動一個線程向 map 寫入值*/ go m.Display() /*啓動一個線程讀取 map 的值*/ var str string /*這裏主要是等待線程結束*/ fmt.Scan(&str) }
package main import ( "fmt" "sync" "time" ) func main() { var lock sync.RWMutex go read(&lock) go read(&lock) go write(&lock) time.Sleep(25000000) fmt.Println("end") } func read(lock *sync.RWMutex) { lock.RLock() fmt.Println("reading") time.Sleep(5000) fmt.Println("read end") lock.RUnlock() } func write(lock *sync.RWMutex) { time.Sleep(1000)//保證先讓讀拿到鎖, 若是沒有就會隨機,不過應該先過read通常會先read. lock.Lock() fmt.Println("writing") time.Sleep(5000) fmt.Println("write end") lock.Unlock() } //結果 reading reading read end read end writing write end end