开发了一个基于key的加锁方案

kzh125 · · 4656 次点击
你这个代码有bug: 我举一个极端的例子: 假设有10个并发传入了相同的key,其中`goroutine_01`先进行`count++`并获取了`Locker`结构体 另外9个卡在了`l := v.(*Locker)`这一行和下一行之间 之后`goroutine_01`又进行`count--`并从map中删除了`Locker`结构体, 然后另外9个goroutine调用的`Locker`函数返回,从而获取了与`goroutine_01`相同的`Locker`结构体 之后又来了10个并发传入了相同key,由于map中已经没有这个key关联的`Locker`结构体,所以获取的是一个新的`Locker`结构体 也就是说后面的10个,和前面剩余的9个用的不是同一把锁,也就起不到加锁的作用
#12
更多评论
………… 一个sync.Map,值是sync.Mutex类型就可以了……
#1
找了下我的代码,大概是这样的 func NewUtil() *Util { return &Util{ locks: &sync.Map{}, } } type Util struct { locks *sync.Map } func (u *Util) Locker(key string) (*Locker, bool) { newlocker := &Locker{ Map: u.locks, Key: key, } v, ok := u.locks.LoadOrStore(key, newlocker) return v.(*Locker), ok } type Locker struct { sync.RWMutex Map *sync.Map Key string } func (l *Locker) Unlock() { l.RWMutex.Unlock() l.Map.Delete(l.Key) }
#2