00:00
同学们大家好,上一讲我们介绍了autom stamp reference带初级流水的原子类,它是该如何使用的,那么对于我们在单线程环境下面入门级别API的调用算是介绍完成,那么接下来我们来继续要写一个在多线程环境下面API问题是如何产生的,我们如何用它来杜绝AB问题的发生?好,那接下来我们来分两步,第一步。我不用它,就用普通的原子操作类,看看会出现什么问题,之后我们再说明为什么要有它,那么也就是我们的AB法则before after,给同学们更加深刻的掌握在高并发多线程环境下面如何控制这个版本。好,那么下面呢,来吧。我们先static奥in,那么这个呢,是我们的第一个啊,不带初级流水不带版本号的,那么下面假设初始值就是100来吧,那么现在第一个线程。
01:02
那么就是我们的T1,那么T1呢,开高。Compare and set,我们期望值啊,相当于这个就是我们的A对吧,那么我们期望是100,如果OK的话,我们改为101,那么中间我们故意暂停十毫秒,那突然。T1这个线程它呢,又反悔了。又把它改回来。也即在T1这个线程范围以内是发生过ABA的。A100B101又改回A100,换句话说中间是有人动过的,好,那接下来你在改的过程当中啊。我呢也没闲着,我这是T2,呃,为了保证让上面成功发生了API,那我一进来的时候,我先停个200毫秒,OK,然后呢,T2呢也不知道,反正呢,因为T1是T1 T2是T2,两个是各自独立的线程,所以呢,T2呢,比如说进来了以后啊,我这儿故意停200毫秒是等上面发生完成ada啊,只是为了好讲课,实际业务上不用停啊,那么他呢,傻不愣登的我也。
02:13
不知道有人动过呀,我还是认为是100,那么是100的话呢,我就改成2022。OK,然后来看看这个操作是否正确,那么现在奥in.get那此时来看一下我们现在这个最新值啊,写写没写进去是不是2022,好,同学们,我们一跑。看一下我们后台演示的效果,结果是什么处2022,所以说这就是什么,明明已经有一个一号线程动过了,但是如果像刚才我们所说的只检查内容。一开始是A100,然后还是A100,我们就认为没有人动过,很乐观对吧,所以说呢,这个时候我们改为2022却是成功的,但是谁也不知道,原来中间有101这个B这种操作有人。
03:02
在捉妖有猫腻的情况,所以如果用传统的、普通的,不带初级流水的,是没有办法解决这个问题的。接下来我们先把代码提出来,然后呢再用我们的初级流水来解决ABA问题。好,那么这个是ABA。发生了,但是呢,原有的这样的简单的搞不定来吧,那么现在呢,我们呢,和刚才一样。Sta reference这个呢,是die。初级流水的好,那么流水号和之前的一样。我们的初始值是100,版本号是一,OK,那么来吧。还是熟悉的配方,还是熟悉的味道。那么两个线程。T1T2用过了,那么这个时候我们就T3和T4,那么通过上一个案例,我相信大家对这些基础的AP已经了解了,不再废话,直接使用,那么来吧,先获得你的版本流水号,OK,那么。
04:03
现在,他的首次。版本号,那同学们过来这儿就是我们的stepmp,那么也就是说T3第一次过来拿的时候,初始值相当于这个A就是100,版本号就是1OK,那么好,我这儿啊故意的停500毫秒。那么。也就是说保障后面的T4线程。初始化拿到的版本号和我一样,那现在相当于说两个线程来抢嘛啊,我们要发生ABA问题后,要让这个T4它呢,没有办法插入成功来,因为别人动过了,那么他的版本号我这儿啊得到的时间。500毫秒以后,那500毫秒T4肯定已经先运行了,所以说他这儿得到的首次版本号是一,那么换句话说就是一开始程序,那么T3和T4啊,得到的值和版本号都是100,都是一,OK好,那么接下来。
05:07
这个停顿节奏完成以后,我们来了,那么T3要做一次ABA操作,那么。带初级流水比较并交换,我希望是100改成了101,然后完了以后呢,就拿我希望的是这个流水号,那么也就是一,完了以后我呢,加个一在上面的流水上改动一下,OK,那么先来说加个一改动了就会变成二好了,那么现在。我们呢,第二个,那么这个时候就是二次流水号,那么首次是一,那么二次的话,那么同学们我们都清楚,那么现在是不是由一。变成了我们的二,OK,好,这是我们的第一个,接下来T3呢?又开始作妖了,改了一次,想了一会儿啊,觉得不合适,我把它改回来,那么101,哎。B就是101又改成A,换句话说这个就是什么,我们的第三次流水和我们对应的值OK,那么好,相当于说T3。
06:10
他干了这个活,那么就是流水号,就是从123干了三次,好了,那么同学们搁到这儿了以后啊,那么我们这儿呢,也继续干脆我这停一秒钟,我这儿停的,停一秒钟是让。或者说是等待。上面的T3线程。发生了ABA。问题好,那么接下来啊,有点类似于说我T4啊。也呢,取得了初始的版本号,和值100和一,那一秒钟以后,我呢,要准备写回去了,此时我也写回去,大家请看,那我们呢,也是compare and set。T3发生了什么我不知道,我们两个是独立,那么我希望是100改成2022完了以后我希望的这个流水值,那么比如说就是一,那么弄上去加个一,那么就是二对吧。
07:15
所以说此时我们呢,来看看我现在由于上面发生了ABA已经提交了什么三次流水号,那么到三了,我手头上的这个台式机,也就是说我弄回去了以后,别人早就已经在我的前面了,那么来看看我们本次的修改这个布尔值是true还是false,然后完了以后我们呢,拿到我们的戳记流水get reference,然后呢,再拿到我们的戳记。流水,然后看看它的版本号是多少,OK吧,好,那么同学们,我们呢,来运行一下文这个程序,看看我们的抽取流水能不能可以帮我们解决ABA问题,来同学们一运行。看看后台出现的效果,大家请看T3首次版本号是一,T4首次版本号是一,没问题,相当于这样T3和T4啊,拿到的都是A100,版本号是一,但是呢,T3在上面干了。
08:13
这么一次把100变成101,此时我提交了流水号是多少二,然后T3呢,又干了一次,把101这个B又改回成100,又提交了他干了什么?第三次流水号这次是多少?是三了,可是我这个T4呢,傻傻的什么都不知道,我去忙了,离开的时候是100带着走的,11回来时候我希望我的业务诉求是要把它改成2022这个值,但是呢,这个版本号我希望11。我提交了以后会变成二,但是理想丰满,现实骨感已经有人动过了,所以说这个时候你T4去提交的时候,大家请看修改是false,当前值是多少还是100,你要提交进去的2022,这个你的修改值作废,那么此时的版本号T4手头上的。
09:01
是一,但真实版本号是三,所以你本次提交作废上不的台面,OK,好,那么通过它,这样我们就完成了我们ABA相关问题的说明和编码的演示。那到这儿我们ABA问题算是暂告一段落,那后续在基于ABA问题这个类啊的引出,我们会在下一章就是原子操作类十八罗汉这一章的话,那么给大家介绍奥market reference,那么后面的内容更加精彩,希望同学们继续跟着杨哥学习,那么接下来呢,我们对问题做一个总结,那么就是一句话,比较要加上版本号一块上,仅凭内容是不足以应付的。好,那么这个就是我们对CS这章所做的全部讲解和代码演示,后续我们再。做一下与第八章相关联的原子操作,那么同学们期待大家继续聆听杨哥的技术分享,谢谢各位,第八章我们到此结束。
我来说两句