00:00
同学们大家好,接下来为大家介绍CS思想的重要落地应用自选所,我们呢?一方面复习一下CS以及自学的思想,另外一方面懂得思想以后,需要把你的思想用代码体现出来,所以我们借鉴CS的思想,给大家介绍自选索还是否记得我们在第四章的时候讲解加入的琐事。说过一个东西叫自选锁,当时提了一嘴,由于还不具备后续的知识,这偃旗息鼓了,那么现在重新续接上开启,那么对于我们源码的深度分析,对于我们C类汇编级别的源码讲完了,那么接下来手下见真章,开工。首先CS和自旋它是什么东东?CS?实现是实现自选锁的基础,那么它是利用CPU指令保证了操作的原子性,这个我们前面上一讲,我们已经说过,以达到枷锁的效果,那么至于说自旋嘛,看字面意思也明白,对吧,自己旋转说过了。
01:04
自己抢不到,只能是什么多抢两次底子嘛,反正反正就是个DOL循环,所以呢,我们获取的线程不会立刻阻塞,不像加斯那样子,那没办法了,可能会被阻塞,那么它呢,是采用循环的方式去多次尝试去获取锁,当线程发现所被占用的时候,会不断的循环判断所的状态,直到你能够获取。好处呢,就是减少了线程上下文切换的这种重量级别的消耗,那么缺点呢,循环呢,也会消耗一点点CPUOK,那么反正嘛,做凡事都要付出代价,只不过是两害相衡取其轻,那么来,同学们。对于open gdk,我们经看到了按shift类叫Java,那么底子的源代码,这个呢,我们已经讲过这段do啊,自旋的循环是什么,我们已经不再赘述,说穿了,所谓的自学翻译成人话就是循环,那么结合到我们的代码,那么也就是我们的读,一般是个无限循环来实现啊,随便你用读外或者外都可以,那么这样一来,一个无限循环当中执行一个CS操作,那么当操作成功返回这个true的时候。
02:11
取凡是false跳出来,循环结束,但是当返回这个是个false的时候取反,那么这个时候就整体就变成了一个处,那么需要重新进来自学。接着执行循环。继续尝试CS的操作,直到返回处为止。好,那么接下来我们要自己实现一个自选锁spring lock,好。那么来各位同学看一下我们的题目要求。那么自选锁的好处,那么循环比较获取呢?没有类似wait这样的阻塞,因为它是通过while循环来保证。那么下面我们要的题目要求是通过CS的操作完成自选锁,假设A线程先进来调用一个lock方法,自己持有锁五秒钟,然后B呢,随后进来发现当前线程。当前呢有线程持有锁,那么所以只能通过自选等待,直到A释放锁以后,B随后才能抢到。好,那么下面我们呢来尝试一下如何完成这个案例。
03:12
首先。前面我们是是不是说过一个东西叫。原子引用大家还有印象吗?那么现在我们呢,就要派上用场喽,分析我们题目的需求就是AB2个线程来抢同一把锁,OK,那么所以说那么各位同学我们呢,我们这么写啊,前面我们讲了原子引用。到这儿我们就可以派上用场来,同学们,那这个时候的话,先理理,再理理我们的思路啊,实现自选锁要用cns的思想,也就说穿了,不能用我们的什么原有的什么那些SYNCH啊,和和GC给我们封装好的洛克洛克。所以说呢,我们这。来这个呢,是我们的原子引用奥reference这个泛型里面就填我们的线程类,好那么现在。
04:00
搁到这儿。我们呢,先拗这么一个原子引用类里面呢,就是我们的各个线程,那么要A线程先进来,要通过S的方法,那么所以说我们要通过CS啊,就要把它包装进我们的reference,纳入到那些guc的原子包下面的一些方法的引用,所以说我们这儿public VO,那么lock。来吧。Public。那么unlock这些呢是匹配的来,那么th.current这个呢,就是当前线程。那这个时候假设A线程进来了,A线程进来以后它是什么意思啊,调用这个类这个方法来,它才具备compare and set cns啊,一个是期望值啊,一个是更新值啊,那假如说首次第一个线程进来,就是A线程进来,我的期望值啊,当然是希望。里面没有一个线程在占有,然后如果是个难是个空的,那么我就把我自己填上去,就是这个thread这一步能跟上。说白了,假设现在杨哥肚子不舒服,想去卫生间去占坑位的话,我当然希望这个坑位是没有的,然后完了以后我用CS回来,希望值是空的,结果它真的也是空的,那么我当然进去。
05:21
卫生间里的坑位里面释放自己的内存,那么一样,如果它是,那说明还没有被占用,那么我就要把自己写进去,然后。此时大家请看,如果这个是个是吧,CS啊成功了,那么这个是个错,那么我们就应该跳出循环对吧,所以说在这我们要取反,OK,那么我们来分析这个思路,第一次进来。A线乘进来里面根本没有人持有所对吧,就是它强调,所以说各个坑位里面,就是那把A写进去,它的CS乘高这一段就是处处取反了以后,那是不是应该跳出这个循环,完成下面的操作工作,A就自己拿到了这把锁,该做什么做什么,所以说在这我们呢。
06:11
直接打过来就是他命,那么第一个线程假设就是A线程进来了,并且它在这块呢石有所成功,好,这是我们的洛克方法,那接下来我们来看看我们的unlock呢,那么同理。它呢,也就是当前这个线程,对吧,谁先拿到这个安洛克了,我们现在要解锁,那假设按照我们刚才是A先执行,A持有这个锁,待会我们会说几秒钟,五秒钟,五秒钟以后A是不是要按lock了,那么所以说呢,它呢也一样。过来这compare and set,那么这个时候A自己要去示范,那么假设现在啊,杨哥在卫生间的三号坑位里面,我准备出来了,那么我当然期望值还是我这个A还是我自己,然后我出来以后,那么是不是把这个值改成了方便其他的线程来占用,这么说能跟上,所以说搁到这儿我们呢,很简单的来模拟这个程序,那么这个时候就是。
07:05
Task。Over,那么解锁成功,OK,那么。按洛克完成好,这个就是洛克,按洛克就这么简单,那么接下来我们呢,过来这按照我们的题目要求。来吧,相当于这个呢,就是我们的。嗯。资源类,那么现在两个线程。一个线程呢,是叫AA呢,他过来了干一件什么事呢?它呢,首先去调用lock a线程线调用这个资源类里面的这个lock方法,我们没有加锁,我们通过的是CS来实现的,对吧,自学,然后按照题目要求弟兄们。A线程A线程先进来,也就是A首先启动,那么呢,来调用买lock方法也是我们这的lock啊,自己持有锁五秒钟好,那么这儿lock完了以后我要。但我的业务逻辑假设要五秒钟完了以后我呢?
08:04
在我们的安洛克解锁没问题吧。那么在这。那么假如说啊,我们这儿呢,就是500毫秒暂停500毫秒,那么保证,那么是不是线程A。相当于说他先启动。线程A先于。B启动OK吧,那么好,那接下来呢,在这块直接过来拷贝。这个呢,就是我们的B,那么B要干的活呢,So easy,就是lock and lock,那么A有锁五秒钟,那500毫秒以后B也该动了吧,但是B动的时候,我们会发现这么一些情况,B过来他也希望是,那有没有可能,没可能,因为此时A先启动,他占着坑了。死除应该是我们的什么A在里面,所以说这个B这一波它呢是false,取反了以后就是错,那么相当于说后面这个B就只能在这儿自学,OK好,那么同学们,我们来看一下我们整个整个程序它的思想和设计。
09:13
那么这个呢,就是没有用snchize,然后直接用CS的思想,A进来,B也进来,大家请看,A没有示范锁的话,B只能在那好端端的等着,那么完了以后,五秒钟以后a task over unlo了,由于B现在呢,一直在外面自学,对吧,一旦发现这个值要A已经走了,A只要是安洛克一走,马上会把。这个呃,更新值变成烂,那么B呢,就一直在这转着,那么突然发现这是个烂了,B马上也就进来强锁,强锁成功以后,相当于这块,那么马上就执行完毕,往下走,那么往下走以后这个B。洛克强索成功了,也马上执行完了又到UN洛克,所以到这儿的话,B完了以后,B马上抢索成功,我们在这洛克这呢,也没做什么太多的工作。
10:05
相当于说在这儿跳出了这个Y,马上进入到下一行,那么就是我们,安洛克此时又到了我们的。洛克,那么现在这个线程就是B,我当然比较并交换,我当然希望值就是我自己完了,我要出去了,这个坑位让出来又恢复成了,那么最终这个b taskoverwork,好那么同学们,这就是我们什么没有用size,完全是实现了这个cns这样的操作,通过它的API,借用它的API用while模拟写了一个我们的自学,好那么同学们,这个就是我们借鉴CS的CS的思想,自己实现一个自选索,那么请大家。
我来说两句