###互斥锁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