github.com/songzhibin97/gkit@v1.2.13/sys/mutex/recursive_mutex_token.go (about) 1 package mutex 2 3 import ( 4 "fmt" 5 "sync" 6 "sync/atomic" 7 ) 8 9 // TokenRecursiveMutex Token方式的递归锁 10 type TokenRecursiveMutex struct { 11 sync.Mutex 12 token int64 13 recursion int64 14 } 15 16 // Lock 请求锁,需要传入token 17 func (m *TokenRecursiveMutex) Lock(token int64) { 18 if atomic.LoadInt64(&m.token) == token { // 如果传入的token和持有锁的token一致,说明是递归调用 19 atomic.AddInt64(&m.recursion, 1) 20 return 21 } 22 m.Mutex.Lock() // 传入的token不一致,说明不是递归调用 23 // 抢到锁之后记录这个token 24 atomic.StoreInt64(&m.token, token) 25 atomic.StoreInt64(&m.recursion, 1) 26 } 27 28 // Unlock 释放锁 29 func (m *TokenRecursiveMutex) Unlock(token int64) { 30 if atomic.LoadInt64(&m.token) != token { // 释放其它token持有的锁 31 panic(fmt.Sprintf("wrong the owner(%d): %d!", m.token, token)) 32 } 33 recursion := atomic.AddInt64(&m.recursion, -1) 34 if recursion != 0 { // 如果这个goroutine还没有完全释放,则直接返回 35 return 36 } 37 atomic.StoreInt64(&m.token, 0) // 没有递归调用了,释放锁 38 m.Mutex.Unlock() 39 }