package mainimport ( "fmt" "github.com/petermattis/goid" "sync" "sync/atomic")// Go version: V1.21.0type ReentryMutex struct { sync.Mutex owner int64//以后锁的拥有者 goroutineid reentry int32//重入次数}func (r *ReentryMutex)Lock(){ gid:=goid.Get() //如果锁的拥有者曾经是以后goroutine,记录下他曾经重入的次数 if atomic.LoadInt64(&r.owner)==gid{ r.reentry++ return } r.Mutex.Lock() atomic.StoreInt64(&r.owner,gid) //初始化可拜访次数 r.reentry=1}func (r *ReentryMutex) Unlock(){ gid:=goid.Get() //如果解锁协程不是以后协程的拥有者,就panic if atomic.LoadInt64(&r.owner)!=gid{ panic(any(fmt.Sprintf("wrong the owner(%d): %d!",r.owner,gid))) } r.reentry-- if r.reentry==0{ atomic.StoreInt64(&r.owner,-1) r.Mutex.Unlock() }}func main() { var wg sync.WaitGroup reentryMutex:=ReentryMutex{} for i := 0; i < 5; i++ { wg.Add(1) go func(index int) { defer wg.Done() reentryMutex.Lock() defer reentryMutex.Unlock() fmt.Printf("Goroutine %d acquired the lock.\n", index) reentryMutex.Lock() defer reentryMutex.Unlock() fmt.Printf("Goroutine %d acquired the lock again.\n", index) }(i) } wg.Wait() fmt.Println("All goroutines have finished.")}