今天聊一聊Golang的互斥锁吧

举报
Regan Yue 发表于 2021/08/28 11:13:41 2021/08/28
【摘要】 今天聊一聊Golang的互斥锁吧今天我们来聊一聊锁吧,我们都知道有并发就有并发安全的问题。对于有的变量不能是并发运行访问的。比如银行的存取款业务,假如可以并发进行的话,你想一想你往银行存这个月的工资200万,你老婆同一时间在银行取200万去做美容。假如不使用锁,你存完之后发现金额没有变化,你老婆取完钱后发现钱也没有变化。你是慌死了,那你老婆不高兴坏了…所以我们这里就需要用到锁,当一个人访问...

今天聊一聊Golang的互斥锁吧

今天我们来聊一聊锁吧,我们都知道有并发就有并发安全的问题。对于有的变量不能是并发运行访问的。比如银行的存取款业务,假如可以并发进行的话,你想一想你往银行存这个月的工资200万,你老婆同一时间在银行取200万去做美容。假如不使用锁,你存完之后发现金额没有变化,你老婆取完钱后发现钱也没有变化。你是慌死了,那你老婆不高兴坏了…

所以我们这里就需要用到锁,当一个人访问这个业务时,就给它加上锁,别人就不能访问了。

看一看这个存钱的例子:

var wg sync.WaitGroup
func main() {
	var money = 2000
	for i:=0;i<10;i++{
		wg.Add(1)
		go func() {
			for j:=0;j<100;j++{
				money += 1
			}
			wg.Done()
		}()
	}
	wg.Wait()
	fmt.Println("最终金额",money)
}

这个例子就是10个人每个人给你存100块钱。这一百块钱分一百次存。这样存完后我们就有三千块钱了。

我们看一看运行结果:

最终金额 3000

好像是没问题哦!那我们加大一下存款金额吧。让10个人每个人存1000,这一千块钱分一千次存,这样我们就会得到一万二千块钱,来看一看运行结果吧!

最终金额 10366

是不是和我们预想得不一样?

这就是出现了并发安全问题。

对于这种问题,我们应该不允许并发访问。

然后我们看看怎么使用互斥锁解决这类问题吧!

func main() {
	var money = 2000

	var mt sync.Mutex

	wg.Add(1)
	go func() {
		fmt.Println("搏达试图抢断")

		mt.Lock()
		fmt.Println("搏达抢断成功")

		money -= 300
		<- time.After(10 * time.Second)

		mt.Unlock()
		fmt.Println("搏达扔了球")
		wg.Done()
	}()

	wg.Add(1)
	go func() {
		fmt.Println("搏达试图跳舞")

		mt.Lock()
		fmt.Println("搏达跳舞成功")

		money -= 500
		<- time.After(10 * time.Second)
		mt.Unlock()
		fmt.Println("搏达放弃跳舞")
		wg.Done()
	}()

	wg.Wait()

}

这段程序的意义是两个协程同时抢锁,跳舞协程先抢到锁的话,搏达就开始跳舞,然后跳完舞解锁,抢断协程开始抢到锁,然后搏达结束跳舞开始抢断。如果抢断协程先抢到锁的话,搏达就先开始抢断然后再跳舞。

运行结果是

搏达试图抢断
搏达抢断成功
搏达试图跳舞
搏达扔了球
搏达跳舞成功
搏达放弃跳舞

我们可以看到,搏达扔了球才能开始跳舞。这就是锁的功劳,让搏达不至于一边跳舞一边抢断而累趴。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

举报
请填写举报理由
0/200