ReentrantLock和AQS源码解读系列预备知识二

AQS所谓的队列的理解

首先要说一下AQS的等待队列和我们常规意义上理解的队列还是有点差别的,因为他的队头的那个结点是获取锁的那个结点,第二个结点才是排队的。或者我们可以换个方式理解,最前面的那个并不是排队的,是正在接受服务的,后面才是队伍,只是为了管理方便,把第一个也加入到队列里而已。举个最好理解的大保健例子,比如小王要去大保健,特别喜欢找13号技师。我打算先介绍几个简单的例子,当然实际情况比这个可能复杂,但是先理解简单的例子为复杂的做铺垫。比如小王去做大保健的时候可能会出现如下几种情况:

技师空着,刚好我可以大保健

小王发现技师空着,二话不说,直接大保健了。
在这里插入图片描述

技师忙着,没人排队,需要创建队伍,小王要开始排队

小王发现技师忙着,那就只能自己等着了,顺便创建个队伍,自己排着,不然后面的人来了就乱了。
然后就给老王贴了个标签SIGNAL,然后就阻塞了。
等老王完成后,发现有SIGNAL,于是就唤醒了小王。
于是小王醒来看技师是否空着,空着就直接大保健了。
头部红色表示阻塞状态,等待状态是SIGNAL表示释放锁的时候要唤醒后继结点。
在这里插入图片描述

技师忙着,有人排队,小王也排队

小王那天去晚了,一看前面那么多人,已经排队了,那怎么办呢,也排个队咯,然后给前面的小王贴了SIGNAL标签,他又想睡觉了,阻塞了。

在这里插入图片描述

技师忙着,有人排队,小王也排队,但是发现前面那哥们有事取消了

排队的时候发现前面的人取消了,就去找非取消的人后面排着。
在这里插入图片描述

老王好了,小李做

老王一会儿工夫就好了,发现有SIGNAL,于是就唤醒了小李。
在这里插入图片描述

总结

本篇主要介绍了一下简单的排队和获取锁的机制,当然AQS真正的流程还有很多细节的地方要讲,比如多线程操作的时候,很多CAS可能会失败,然后会继续自旋,可能会造成结点有问题,比如在排队的时候,也是抢着排最后的,可能会出现这个方法执行不成功:
在这里插入图片描述
也就是虽然我是排着了,但是前面那个人并不认为我是在他的后面,可能这样的情况有多个,就会产生一对结点要不停的自旋排队:
在这里插入图片描述
虽然最终还是会用自旋的方式加到队尾:
在这里插入图片描述
但是多线程情况下,可能会出现问题,比如高并发的情况一直会有大量线程在自旋排队,所以为什么唤醒后继的这段不是从头遍历,而是从尾遍历:
在这里插入图片描述
网上有说是因为会丢失在自旋排队的那些结点,不合理,好像有点道理,不过我觉得,如果要找到排在最前面的非取消的结点,可以直接从s开始遍历,获得到就break就好了,就算有丢失也没关系,丢失的自旋照样会进来,如果刚好就是没找到,也没关系,丢失的结点自旋回来还是可以获得锁的,他们不是不来,只是来晚了点。我觉得可能是考虑如果从头开始遍历,出现异常情况,后续的结点全部取消状态,下面的代码是和上面的是可以同时运行的:
在这里插入图片描述
然后有种特殊情况,尾部有源源不断的来新结点,这样是不是可能就在这个遍历里无限向后遍历了,或许这种情况不太可能,是我想多了。不过确实从尾部遍历就不用考虑这些情况,只在这一刻的尾部往前遍历,就能找到最前面符合要求的结点,找不到也没关系。其实就是担心高并发的情况下,这个遍历的速度还没有结点添加到尾部的来的快,那就等于无限遍历了!

好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值