package locker import ( "log" "sync" "github.com/charlienet/go-mixed/redis" ) var empty = &emptyLocker{} type Locker struct { once sync.Once distributedLocker DistributedLocker // 分布式锁 mu locker } func (w *Locker) WithRedis(key string, rdb redis.Client) *Locker { return w } func (w *Locker) WithDistributedLocker(d DistributedLocker) *Locker { return w } func (w *Locker) Synchronize() *Locker { w.once.Do(func() { w.mu = NewLocker() }) return w } func (w *Locker) Lock() { w.ensureLocker().mu.Lock() } func (w *Locker) Unlock() { w.ensureLocker().mu.Unlock() } func (w *Locker) TryLock() bool { return w.ensureLocker().mu.TryLock() } func (w *Locker) ensureLocker() *Locker { w.once.Do(func() { if w.mu == nil { w.mu = empty } }) return w } type SpinLocker struct { Locker } func (w *SpinLocker) Synchronize() { w.once.Do(func() { w.mu = NewSpinLocker() }) } type WithRWLocker interface { rwLocker Synchronize() WithRWLocker } type RWLock struct { once sync.Once mu rwLocker } func (w *RWLock) Synchronize() WithRWLocker { w.once.Do(func() { w.mu = NewRWLocker() }) return w } func (w *RWLock) Lock() { w.ensureLocker().mu.Lock() } func (w *RWLock) TryLock() bool { return w.ensureLocker().mu.TryLock() } func (w *RWLock) Unlock() { w.ensureLocker().mu.Unlock() } func (w *RWLock) RLock() { w.ensureLocker().mu.RLock() } func (w *RWLock) TryRLock() bool { return w.ensureLocker().mu.TryRLock() } func (w *RWLock) RUnlock() { w.ensureLocker().mu.RUnlock() } func (w *RWLock) ensureLocker() *RWLock { w.once.Do(func() { if w.mu == nil { log.Println("初始化一个空锁") w.mu = empty } }) return w }