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  }