00:00
各位同学大家好,我们继续通过前面的我们的基础案例贝案例的解决和编写,我们已经完成了我们的spring BOO和red的整合,写了一个最简单的小DEMO,完成我们的一个下单减库存的操作,Rest风格地址,点一下这个链接,马上库存去判断,并完成了我们的下单减库存的操作,前后台打印出对应的返回。正常情况减一下更新库,异常情况统统在这儿了啊,我这就写的非常简单了,就没有像我们电商项目或者金融项目上有N多种分支啊,商品售完也许是活动结束,也许是电容超时啊等等等等,都归为了这个异常情况,那么这段代码呢,只是一个小DEMO。主要我们研究的是red分布式所的演化,告诉大家为什么我们最后要red这么一个东西,那么其他的请大家呢,忽略好,那么接下来我们已经完成了我们的一个最基本最简单的不和ready整合的,而且测试通过我们大家请看。
01:01
一号机没错吧,现在呢,第97号商品卖出去,还剩下96件,那我们现在换成。二号机,那么大家请看第96号商品卖出去了,安全库存还剩下95件服务提供编号22222号机,好,那么完成了这些了,以后希望大家跟着我来。找他求吐槽,我们从单机版将会慢慢的。过渡到我们的分布式微服务架构一层一层的部署,那么我会让大家体会的到,为什么要做传统行业的互联网程序员是薪水提升有限的,如果你去做互联网行业的程序员,这样才会更加的有前途,那么这是为什么呢?同学们请注意。再次强调。Java程序分两种。传统行业。就是左边一个树形菜单对吧,点一下,然后呢,右边一个父母表单,从上填到下,各种增删改查点一下保存,往数据库插入一条记录成功哦耶,那么这个就是经典的Miss系统对吧?信息管理系统类似的。
02:13
这是一种普通的登上改查,大部分同学呢,如果你长期做这样的项目,基本上是没什么搞头,那么接下来走起,我们来看看互联网的要求。第一个。我们。把这个就当做我们的单机版的程序,那么请大家思考一下,一号机二号机都是一样的啊。那么你们认为这一行现在我的从43行到57行这段业务的主体逻辑代码?在高并发下面会有什么样的问题?好,我暂停一下录屏,同学们请思考来,各位亲,我们都清楚啊,如果你是个单机版。这段代码没有错,现在我们不要去挑它的对错程序啊,有两种,一种叫先完成后完美。
03:01
另外一种说法呢,就叫先功能后性能,功能我们已经强调过了,你能说这个错,每点一下是不是卖出去一件商品库存更新啊?跑得通啦。极其简单,就是么,1.set命令。那么下面的问题是,你这个是单机版。兄弟们。如果在多线程下面呢?第一个问题43 44行,我故意先写成这样,你告诉我这两行是原子性的吗?有没有可能第一个线程跑到这儿停了。然后下面的另外一个给他的数据干串了,比如说最后一个库存一还是零,零还是一。这两行不是原子的吧?第二个如果商品大于零的话,我们再进行,请问有没有可能某个现场爆炸?刚刚到这儿的时候停了。另外的线程判断了以后冲进来给这个库存数不OK,最经典我们是不是学过一个东西叫卖票,我们都明白卖票要去判断一下它的票数是否大于零,那么在高并发多线程的环境下,这样的单机版的程序上线了,是100%会出故障的,这个都不用多说,想想我们的卖票程序,杨哥讲过的GOUC。
04:17
对吧,所以说我们这个程序挑出来第一个问题,单机版你勉勉强强凑合能用,但是多线程高并发这段程序是不OK的,所以说。我们现在得到的一个结论,单机版没有加锁,这是不可以的,那么请问如何修改呢?那么一想到单机版的锁,那么同学们就应该清楚我们之前画过的这张图,GVMGVM层面的加锁是不是就叫单机版的锁呀?那什么叫单机版的锁?注?粗糙最简单的说法是不是要加至少给个面子啊,咱们是不是得加个SYNCH啊?
05:00
OK,好,那么省得他待会不停的这个热启动,我先把它暂停,那么现在我们的代码。做一下最简单的修改,那么好,外面当然你可以定义一个对象啊,我这呢就选一个,我这儿呢,最经典的是不是可以整一个this这一波兄弟们OK吧,那么完成这个以后,一号机是这么改,我们二号机是不是也这么改?至少第一步。我们在。单机版的。多线程的环境下加了SY可以保证不出错了吧?OK,好,这是第一步。第二步,我想问问一下大家。我们在学习GPM单机锁的时候学过两个,一个叫snchize,另外一个是不是叫re lock。那么请问。我们在实际工作中加S加lock,表面上是不是都可以啊?那实际上请告诉我,你们觉得这两个会有什么区别,或者这个问题再换一下。
06:10
我们没有加锁并发下面数字肯定不对,就像卖票一样会出现。重票、错票、复票的现象,OK,那接下来我们的问题是思考一下,我们刚才加了这是最朴素最自然的想法,那么可不可以加这个?那么还是说。到底是应该是加他还是加他还是两个都可以,请大家思考。首先。继续复习这两把锁的特性和利益关系相关联。第一个。我们说过synchize是什么?G面GM层面的锁,当然也是啊,区别就是大家看这个颜色,Snchize它是不是Java层面的关键字啊,但是我们的re look它是个啥?它是不是一个类啊,那么好,现在我们来写出来啊。
07:01
一般我们的private final lock lock等于new lock,我相信这个行代码大家都不陌生,对吧,都讲过直接来自于。我们的lock的标配的参数的通用的定义对吧?只要你定义lock差不多上面就是private final,因为这个也不会有谁去改加把锁了,一键滑动式解锁对吧,就像你去卫生间拉门栓一样的。那么这个时候的问题就来了,到底是加这个lock还是加NCH呢?这个是一个类,这个是个S,那么接下来要看你的业务。这两个锁的特点是不一样,第一种我们学过加锁或者叫多线程的状态有两种,那这两种分别是什么东西?第一个叫不见不散。还记不记得兄弟们第二个这个时候叫叫什么,是不是叫过时不候?
08:04
同一房,那么什么意思呢?如果你加的是s nice,你这个线程,第一个线程进来了,好说他在里面爽着,但是其他线程你懂的,除非说这段代码。运行完成。或者报异常,总之一句话就是非得是第一个线程示范了以后,其他外面等这个线程数才能进来,那么有没有可能在如果你加这种锁的话,就特别容易导致什么线程积压和拥堵,OK,因为它是取不到他不走的,那么这个就变成什么不见不散,那么下面就会有一大堆的线程卡在外面,第一个可能他的业务逻辑可能需要处理五秒钟在这转着呢,那你没办法,下面外面的只能等着。但是呢,如果你加我们的圆圈的look啊,我们都学过一个东西,复习一下啊,在这多啰嗦两句。那么这个时候我们的洛是不是学过一种方法叫TRY落,同学们还有印象吧?那么我们这是不是讲过TRY落,那么我们为什么要学这个,它有个前提,就是有没有可能啊?
09:04
我。等着。觉得啊。时间太长了,我想放弃等待。可不可以,兄弟们有这种情况吧,好,或者说什么。给我。一个。规定的时间内。拿不到锁。我。再饭吃。那么这样是不是就可以规避snchize这样死等的这种情况,我们可以更加灵活的一样,是不是应该有一个东西叫过时不候?那么回想起我们之前讲过的。UC的基础知识。别忘了这个是不是也是一种标配,那么好,它有请大家看一下洛,我们刚上面定义了它可以有种东西叫try lock try lock的意思就是尝试能不能抢到,抢到了立马进来干相关的业务逻辑,抢不到不好意思啊,本次没有抢到,看你后面业务逻辑是直接放弃走人了,还是再来一次,类似于自学,我们再抢抢OK,这种东西就是比较痛快,Try look抢得到。
10:16
我直接干,抢不到我直接放弃,第二种折中一点,呃,你也别那么。某我们用出lo给个时间,比方说我抢锁时间,我给你三秒钟,这三秒钟以内我抢到了,我直接要我抢不到我再放弃折中一点好,那么所以说同学们。我们在加速的时候要看你的业务,第一种就是下死命令啊,你甭跟我废话。一定要抢到,抢不到就给我一直等着石,等狠石烂,OK,那么这种这种业务要求你就加S,那假设另外一种的话,那么就是刚才我们。各位亲,我们看到的if是不是我们的洛点?这是不是有个叫try look,兄弟们,这波。
11:02
OK吧,那么如果说啊,当然他这一共有水烫了不管啊。这只是说一个意思啊,那么如果说他能够抢到,那么我们是不是在洛点洛,然后接下来再写你的业务逻辑基本上的代码,是不是就是我们这一圈,然后在里面再写一个try lock的话,Final里UN lock将它关闭,那么这个就是直接抢到开高抢不到我放弃。第二种情况是不是就是我们的落点try lock,你给我个时间,比方说。三秒钟。我抢我我抢走的时间,我愿意这一栏如果直接抢到啊最爽,如果没有抢到,我可以有三秒钟的。小规模小范围的等待,然后我再柔和一点,再放弃或者是干活,那么所以说请同学们注意,单机版加锁是有这两种情况哦,你在公司要看你的业务。当然我们在这儿无所谓教学环境,但是你在公司里面的时候就一定要注意,要思考加锁到底是加SNCH还是加这样的穿好吧,那么标配的代码都在这给你官网上写好了,直接粘就行好的。那么在这呢,我们呢就。
12:13
说到这儿,所以说呢,我们。跑过来这了以后先完成我们的第一步,是不是解决我们的单机板锁的问题。
我来说两句