github.com/songzhibin97/gkit@v1.2.13/internal/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 int32
    14  }
    15  
    16  // Lock 请求锁,需要传入token
    17  func (m *TokenRecursiveMutex) Lock(token int64) {
    18  	if atomic.LoadInt64(&m.token) == token { // 如果传入的token和持有锁的token一致,说明是递归调用
    19  		m.recursion++
    20  		return
    21  	}
    22  	m.Mutex.Lock() // 传入的token不一致,说明不是递归调用
    23  	// 抢到锁之后记录这个token
    24  	atomic.StoreInt64(&m.token, token)
    25  	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  	m.recursion--         // 当前持有这个锁的token释放锁
    34  	if m.recursion != 0 { // 还没有回退到最初的递归调用
    35  		return
    36  	}
    37  	atomic.StoreInt64(&m.token, 0) // 没有递归调用了,释放锁
    38  	m.Mutex.Unlock()
    39  }