Mutex和RWMutex

Golang 中的有两种锁,为 sync.Mutex 和 sync.RWMutex

  • sync.Mutex 的锁只有一种锁:Lock(),它是绝对锁,也称互斥锁,同一时间只能有一个锁。
  • sync.RWMutex 叫读写锁,它有两种锁: RLock() 和 Lock()
    • RLock() 叫读锁。它不是绝对锁,可以有多个读者同时获取此锁(调用 mu.RLock)。
    • Lock() 叫写锁,它是个绝对锁,就是说,如果一旦某人拿到了这个锁,别人就不能再获取此锁了

1 Mutex是互斥锁

2 RWMutex是读写锁,读写锁可以让多个读操作同时并发,同时读取,但是对于写操作是完全互斥的。也就是说,当一个goroutine进行写操作的时候,其他goroutine既不能进行读操作,也不能进行写操作。

var count int
var wg sync.WaitGroup
var rw sync.RWMutex
func main() {
    wg.Add(10)
    for i:=0;i<5;i++ {
        go read(i)
    }
    for i:=0;i<5;i++ {
        go write(i);
    }
    wg.Wait()
}
func read(n int) {
    // 读锁是RLock(),
    rw.RLock()
    fmt.Printf("读goroutine %d 正在读取...\n",n)
    v := count
    fmt.Printf("读goroutine %d 读取结束,值为:%d\n", n,v)
    wg.Done()
    rw.RUnlock()
}
func write(n int) {
    // 写锁是Lock()
    rw.Lock()
    fmt.Printf("写goroutine %d 正在写入...\n",n)
    v := rand.Intn(1000)
    count = v
    fmt.Printf("写goroutine %d 写入结束,新值为:%d\n", n,v)
    wg.Done()
    rw.Unlock()
}
View Code

map由于是非线程安全的,可以自己通过对map对象加锁来实现线程安全,具体操作是给新构造的map对象添加增删改查的方法,其中除了查添加读锁,其余的都是写锁,进而实现了线程安全,

// 安全的Map
type SynchronizedMap struct {
   rw *sync.RWMutex
   data map[interface{}]interface{}
}
// 存储操作
func (sm *SynchronizedMap) Put(k,v interface{}){
   sm.rw.Lock()
   defer sm.rw.Unlock()

   sm.data[k]=v
}
// 获取操作  只有这个加的是读锁,
func (sm *SynchronizedMap) Get(k interface{}) interface{}{
   sm.rw.RLock()
   defer sm.rw.RUnlock()

   return sm.data[k]
}
// 删除操作
func (sm *SynchronizedMap) Delete(k interface{}) {
   sm.rw.Lock()
   defer sm.rw.Unlock()

   delete(sm.data,k)
}
// 遍历Map,并且把遍历的值给回调函数,可以让调用者控制做任何事情
func (sm *SynchronizedMap) Each(cb func (interface{},interface{})){
   sm.rw.RLock()
   defer sm.rw.RUnlock()
   for k, v := range sm.data {
       cb(k,v)
   }
}
// 生成初始化一个SynchronizedMap
func NewSynchronizedMap() *SynchronizedMap{
   return &SynchronizedMap{
       rw:new(sync.RWMutex),
       data:make(map[interface{}]interface{}),
   }
}
View Code

参考:https://mp.weixin.qq.com/s/wyezW1swNlDkXi4V-ABa-w

http://www.coder55.com/article/27284

 

posted on 2021-01-07 20:28  吃我一枪  阅读(292)  评论(0编辑  收藏  举报

导航