两张图,让你理解代码中的“锁”

资源是维持人们日常生活和社会发展的重要因素,历史上各个国家为了争夺资源引发的战争也不胜枚举,远了的不说,2003年的伊拉克战争大家应该还有印象吧(啥?你是00后?)。资源的重要性不仅体现在现实生活中,在二进制世界里,由于争夺资源引起的冲突也屡见不鲜。

《聊聊同步、异步和回调》这篇文章里有讲到「异步」的概念,这个「技术」看上去很美好,但在实际应用的时候很容易挖坑把自己埋起来,即便是久经「码」场的老猿,一不留神也会在这里栽跟头。而这些问题,归根结底都是「资源」的管理问题。我们来看一个具体的栗子。

假设你在XX银行有个账户,里面有一百万。今天上午8点,有两个客户同时向你的账户里转入了一笔钱,这两个操作是「异步」进行的,账户余额就是要操作的「数据资源」。

我们把转账操作分解成以下三步:

1、款项到达银行

2、查询账户余额

3、转入款项与余额求和并更新账户余额

现在我们来看如果这两个「异步」操作按下图中的流程执行会有什么结果:

两张图,让你理解代码中的“锁”

很显然,由于两个操作的异步性,导致最终的账户余额在八点零四分被更新成了180W,另外的50W转账金额不见了!赔钱!

在上述流程中,我们可以看到两个操作分别在八点零一分和八点零二分读取了账户余额,但是账户余额在八点零三分被更新了,而由于两个操作是「异步」执行,右侧的转账过程并不知道之前拿到的账户余额已经过期,继续在八点零四分计算出了错误的结果,并将错误的数据写入了数据库。

很显然,这个问题的产生是由于两个转账行为在操作账户余额这个「资源」时,有一定的「时间重叠」。要解决这个问题,必须让它们在操作帐户余额时是「顺序」的,也就是消除「时间重叠」

现在,我们假设有一把「锁」,可以将账户余额「锁住」,当某个转账过程获得这把「锁」时,另一个转账过程只有等这把「锁」被释放后,才能继续操作账户余额:

现在好了,我们保住了左侧转账过程的50W!但是细心的同学肯定也发现了新的问题,整个转账过程的耗时变长了!事实确实如此,因为我们为了解决「资源」访问的问题,强行用「锁」将两个「并行执行」的过程变成了「顺序执行」。「金钱」和「时间」那个更重要,你懂得~!

现在大伙应该明白「锁」是「锁」啥的了吧?

来源:给产品经理讲技术,本文观点不代表自营销立场,网址:https://www.zyxiao.com/p/96066

发表评论

电子邮件地址不会被公开。 必填项已用*标注

侵权联系
分享本页
返回顶部