Go 并发访问地图

示例

进行中的映射并发并不安全。如果要同时访问它们,则必须加锁以对其进行读写。通常,最好的选择是使用,sync.RWMutex因为您可以拥有读写锁。但是,sync.Mutex也可以使用a。

type RWMap struct {
    sync.RWMutex
    m map[string]int
}

// Get是用于从基础映射中获取值的包装器
func (r RWMap) Get(key string) int {
    r.RLock()
    defer r.RUnlock()
    return r.m[key]
}

// Set是用于设置基础映射中键的值的包装器
func (r RWMap) Set(key string, val int) {
    r.Lock()
    defer r.Unlock()
    r.m[key] = val
}

// Inc增加键的RWMap中的值。
//   这比r.Set(key,r.Get(key)++)更令人愉快
func (r RWMap) Inc(key string) {
    r.Lock()
    defer r.Unlock()
    r.m[key]++
}

func main() {

    // 在里面
    counter := RWMap{m: make(map[string]int)}

    // 获取读锁
    counter.RLock()
    _ = counter.["Key"]
    counter.RUnlock()

    // 以上可以替换为
    _ = counter.Get("Key")

    // 获取写锁
    counter.Lock()
    counter.m["some_key"]++
    counter.Unlock()

    // 以上将需要写成 
    counter.Inc("some_key")
}

包装函数的权衡是在基础图的公共访问与正确使用适当的锁之间。