12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- package lock
- import (
- "sync"
- "sync/atomic"
- )
- type mutex struct {
- *sync.Mutex
- count int32
- }
- type GranularityLock struct {
- m map[string]*mutex
- l sync.Mutex
- }
- func NewGranularityLock() *GranularityLock {
- return &GranularityLock{
- m: make(map[string]*mutex),
- }
- }
- func (l *GranularityLock) Lock(key string) {
- l.l.Lock()
- var m *mutex
- var ok bool
- if m, ok = l.m[key]; !ok {
- m = &mutex{Mutex: &sync.Mutex{}, count: 1}
- l.m[key] = m
- } else {
- atomic.AddInt32(&m.count, 1)
- }
- l.l.Unlock()
- m.Lock()
- }
- func (l *GranularityLock) TryLock(key string) bool {
- l.l.Lock()
- m, ok := l.m[key]
- if !ok {
- return false
- }
- locked := m.TryLock()
- l.l.Unlock()
- return locked
- }
- func (l *GranularityLock) Unlock(key string) {
- l.l.Lock()
- m, ok := l.m[key]
- if !ok {
- return
- }
- atomic.AddInt32(&m.count, -1)
- if atomic.LoadInt32(&m.count) == 0 {
- delete(l.m, key)
- }
- l.l.Unlock()
- m.Unlock()
- }
|