package utility
import (
"fmt"
"sync"
"sync/atomic"
)
type LockObj struct {
Lock *sync.Mutex
Num int64
}
type KeyLock struct {
globalLock sync.RWMutex
locks map[interface{}]*LockObj
}
func (l *KeyLock) getLock(key interface{}) *sync.Mutex {
l.globalLock.RLock()
if lockObj, ok := l.locks[key]; ok {
atomic.AddInt64(&lockObj.Num, 1)
l.globalLock.RUnlock()
return lockObj.Lock
}
l.globalLock.RUnlock()
// 如果不存在该锁,则加写锁并创建一个新的
l.globalLock.Lock()
defer l.globalLock.Unlock()
// 双重检查,确保在加写锁后没有其他 goroutine 创建锁
if lockObj, ok := l.locks[key]; ok {
atomic.AddInt64(&lockObj.Num, 1)
return lockObj.Lock
}
lockObj := &LockObj{
Lock: &sync.Mutex{},
Num: 1,
}
l.locks[key] = lockObj
return lockObj.Lock
}
func (l *KeyLock) Lock(key interface{}) {
l.getLock(key).Lock()
fmt.Println("获取锁成功, areaId = ", key)
}
func (l *KeyLock) Unlock(key interface{}) {
l.globalLock.Lock()
lockObj, ok := l.locks[key]
if !ok {
l.globalLock.Unlock()
fmt.Println("Unlock 失败,未找到锁,areaId =", key)
return
}
lockObj.Lock.Unlock()
fmt.Println("Unlock 释放锁成功,areaId =", key)
if atomic.AddInt64(&lockObj.Num, -1) == 0 {
delete(l.locks, key)
}
l.globalLock.Unlock()
}
func NewKeyLock() *KeyLock {
return &KeyLock{
locks: make(map[interface{}]*LockObj),
}
}一个完整的加锁和获取锁示例
最后
以上就是名字长了才好记最近收集整理的关于golang一个常见的锁问题及解决的全部内容,更多相关golang一个常见内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复