KeyLock:细粒度的Lock实现

相比单个GIANT LOCK这种粗暴的方式,有时候我们需要更加细粒度的锁。最近一个Golang群里一些人在讨论这个问题,也就顺便写点代码,来验证一点小观点。代码里用了二次检查来避免大部分情况下的giant lock,经过验证确实对效率有较大的提升(降低大概40%的开销)。

package keylock

import "sync"

type KeyLock struct {
	giantLock sync.Mutex
	locks     map[string]*sync.Mutex
}

func NewKeyLock() *KeyLock {
	return &KeyLock{
		giantLock: sync.Mutex{},
		locks:     map[string]*sync.Mutex{},
	}
}

func (self *KeyLock) getLock(key string) *sync.Mutex {
	if lock, ok := self.locks[key]; ok {
		return lock
	}

	self.giantLock.Lock()

	if lock, ok := self.locks[key]; ok {
		self.giantLock.Unlock()
		return lock
	}

	lock := &sync.Mutex{}
	self.locks[key] = lock
	self.giantLock.Unlock()
	return lock
}

func (self *KeyLock) Lock(key string) {
	self.getLock(key).Lock()
}

func (self *KeyLock) Unlock(key string) {
	self.locks[key].Unlock()
}

func (self *KeyLock) KeyLocker(key string) sync.Locker {
	return self.getLock(key)
}

type KeyRWLock struct {
	giantLock sync.Mutex
	locks     map[string]*sync.RWMutex
}

func NewKeyRWLock() *KeyRWLock {
	return &KeyRWLock{
		giantLock: sync.Mutex{},
		locks:     map[string]*sync.RWMutex{},
	}
}

func (self *KeyRWLock) getLock(key string) *sync.RWMutex {
	if lock, ok := self.locks[key]; ok {
		return lock
	}

	self.giantLock.Lock()

	if lock, ok := self.locks[key]; ok {
		self.giantLock.Unlock()
		return lock
	}

	lock := &sync.RWMutex{}
	self.locks[key] = lock
	self.giantLock.Unlock()
	return lock
}

func (self *KeyRWLock) Lock(key string) {
	self.getLock(key).Lock()
}

func (self *KeyRWLock) Unlock(key string) {
	self.locks[key].Unlock()
}

func (self *KeyRWLock) RLock(key string) {
	self.getLock(key).RLock()
}

func (self *KeyRWLock) RUnlock(key string) {
	self.locks[key].RUnlock()
}

func (self *KeyRWLock) KeyLocker(key string) sync.Locker {
	return self.getLock(key)
}

func (self *KeyRWLock) KeyRLocker(key string) sync.Locker {
	return self.getLock(key).RLocker()
}

github: https://github.com/xiaonanln/keylock

转载于:https://my.oschina.net/u/2560355/blog/596409

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值