package lockkey import ( "fmt" "sync" ) type LockByKey struct { m map[string]*sync.RWMutex l sync.Mutex } func NewLockByKey() *LockByKey { return &LockByKey{m: make(map[string]*sync.RWMutex)} } func (lk *LockByKey) Lock(key string) { lk.l.Lock() defer lk.l.Unlock() mu, ok := lk.m[key] if !ok { mu = &sync.RWMutex{} lk.m[key] = mu } mu.Lock() } func (lk *LockByKey) Unlock(key string) { lk.l.Lock() defer lk.l.Unlock() mu, ok := lk.m[key] if !ok { panic(fmt.Sprintf("unlock non-existent key: %v", key)) } mu.Unlock() }