博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
golang非阻塞锁的简单实现
阅读量:6396 次
发布时间:2019-06-23

本文共 1208 字,大约阅读时间需要 4 分钟。

  hot3.png

对于复杂类型如 container/list ,需要在所有读写操作上使用 sync.mutex 互斥锁以保证数据一致性,互斥锁并发情况下,Lock 操作会阻塞,一直等到其他线程Unlock,但是有的时候因为有一个耗时比较长的操作一直占用锁,我们想让其他线程不在Lock上一直阻塞,而是直接走其他业务流程。

举一个很简单的场景:在多人并发抽奖环节,为了保证不出现负库存,我们可以通过竞争锁,第一个获取锁的人可能中奖,而其他并发过来的请求获取锁失败(而不是一直阻塞在Lock()),直接当做未中奖处理。

思考了一下,有一个思路,我们可以用两道锁,第一道锁用来判断锁状态,第二道锁才是真正的耗时任务用的锁。

直接上代码

type NBLocker struct{	l1 sync.Mutex	l2 sync.Mutex	locked bool}func (NBLocker *NBLocker) Lock() (success bool) {	NBLocker.l1.Lock()	defer NBLocker.l1.Unlock()	if NBLocker.locked == false {		NBLocker.locked = true		success = true		NBLocker.l2.Lock()	}	return}func (NBLocker *NBLocker) Unlock() {	NBLocker.l1.Lock()	defer NBLocker.l1.Unlock()	NBLocker.locked = false	NBLocker.l2.Unlock()}

使用

type foo struct {	mux NBLocker}func (self *foo) Bong(wg *sync.WaitGroup) {	defer wg.Done()	if !self.mux.Lock() {		fmt.Println("获取锁失败")		return	}	defer self.mux.Unlock()	time.Sleep(time.Second) //停顿一秒	fmt.Println("bong~")}func main() {	f := &foo{}	wg := &sync.WaitGroup{}	wg.Add(4)	go f.Bong(wg)	go f.Bong(wg)	go f.Bong(wg)	time.Sleep(time.Second *2)	go f.Bong(wg)	wg.Wait()}

如果获取第二道锁失败,NBLocker.Lock() 方法会直接返回false,这时候只需要判断一下就可以直接跳过"抽奖环节"

以上例程输出

获取锁失败获取锁失败bong~bong~

 

转载于:https://my.oschina.net/cxz001/blog/872951

你可能感兴趣的文章
模仿与创新
查看>>
Python用subprocess的Popen来调用系统命令
查看>>
Java NIO与IO的差别和比較
查看>>
.NET源代码的内部排序实现
查看>>
解决Strict Standards: Only variables should be passed by reference
查看>>
解决JBoss只能通过localhost(127.0.0.1)而不能通过IP访问
查看>>
MS SQL处理双引号(DoubleQuote)函数
查看>>
[智能架构系列]什么是Buddy智能开发框架
查看>>
三十一、关于android camera setParameters出错
查看>>
【收藏】QCIF、 CIF、2CIF、DCIF、D1(4CIF)格式介绍
查看>>
hdu 3836 Equivalent Sets (tarjan缩点)
查看>>
一些iOS高效开源类库(转)
查看>>
JAVA编程心得-JAVA实现CRC-CCITT(XMODEM)算法
查看>>
C# DES加密
查看>>
浅谈Oracle分区表之范围分区
查看>>
IBM Tivoli NetView网管软件实战
查看>>
IPSec逻辑体系架构
查看>>
Exchange 2013部署系列之(六)配置邮件流和客户端访问
查看>>
List of Free Programming books
查看>>
思考Android架构(二):像Android框架,如何(How-to)吸引开发者来使用它呢?
查看>>