AQS的思想(稳定思想):即使确定了正常节点,这个节点也可能下一秒异常,即使找到了正常节点,这个节点可能只是异常status=0/-1的节点,这些都不要紧,都只是在自己旋转‘生命周期’里面和自己所看到的 最大可能的保证队列的稳定状态,如果判断错了,其他节点会帮着处理直到队列真正的稳定。

AQS的思想(出队思想):通过head=-1出队,head=0出队失败(外部线程不会再次调用head出队)后面节点就要自行出队。(unlock方法会被没有进入队列抢到了锁的线程调用,队列中获取到锁的线程执行完之后也会调用)

队列走向稳定时候,是多个节点线程在调节某一个节点,并且还有一个出队的线程在调节head。

ReentrantLock#AQS是一个FIFO的队列,通过head来出队,通过taill入队。

  1. 队列稳定状态
  2. 队列处于没有稳定的中间态
  3. 队列稳定时候出队
  4. 队列没有稳定时候出队。

节点状态分为:正常status=-1/0,异常status=0/-1,异常status=1。Head节点一定是正常节点(status=0/-1,不可能=1,因为如果头结点获取锁后异常了,头节点.prev=null,在cancelAcquire方法里面执行while (pred.waitStatus > 0)就会抛出异常,整个代码都无法执行了)。区分节点是不是正常判断标准是status值(线程异常了只能通过节点的状态才能看出来,所以肯定有错误,都是尽可能的保证队列的稳定性,后面见到)。也就是说 异常status=0/-1跟正常节点是一样的,能够被作为前驱并且通过它也能够出队后面的节点(作为前驱不要紧,关键在于能不能像正常节点一样唤醒后面出队),因为head唤醒 异常status=0/-1节点时候跟唤醒正常节点一样能够再次去唤醒后面的节点(不会导致队列出不了队,异常status=0/-1节点线程里面的执行逻辑会自动判断去唤醒)。head唤醒 异常status=1节点时候可能不能够再次去唤醒后面的节点(因为status=1节点可能不会再去执行唤醒的代码)。

队列稳定状态(能够正常出队):

  前驱:回路中前面status正常节点

  后驱:回路中后面status正常节点

每2个正常节点构成前驱后继关系,两两相连是正常节点,其余不管,或者中间有异常节点:

达到稳定的中间状态:

调整都是以栅栏作为边界的,2个status正常节点中间不会再有statsu正常节点。每个节点都只保证自己前面的队列是稳定的,不管后面的。

Status正常不一定是正常节点,但是在做正常节点调整法的一定是正常节点,status异常一定是异常节点。

队列走向稳定状态时候:

真正正常节点调整方法:1找前驱status正常节点,2和这个节点建立后驱关系,2设置这个节点=-1。然后自己阻塞,自己阻塞之后前驱节点异常了不管了。

异常节点调整方法:1找前驱status正常节点  2设置自己=1  3帮助建立后驱关系  4自己.next=自己。 建立后驱关系之后前驱节点异常了不管了。

结论1:从前往后找,可能断开,如果不是因为自己.next=自己,那么从前往后也能找到所有的正常节点和部分异常节点。从后往前找,可以找到所有的status正常的节点,并且还会找到部分status异常节点。

结论2:真正正常节点‘生命周期’里面 开始旋转  到确定找到正常前驱那个时间点  再到阻塞,异常节点‘生命周期’里面 开始旋转到  确定正常前驱  再到退出,都是尽可能的建立正确的前驱后继关系  把队列变成稳定状态,自己阻塞了或者异常退出了  前驱后继关系不正确了  就不管了了,交给其他还在旋转的节点去处理。

AQS的思想(个人总结):即使确定了正常节点,这个节点也可能下一秒异常,即使找到了正常节点,这个节点可能只是异常status=0/-1的节点,这些都不要紧,都只是在自己旋转‘生命周期’里面和自己所看到的 最大可能的保证队列的稳定状态,如果判断错了,其他节点会帮着处理直到队列真正的稳定。

只有节点都阻塞了,异常节点都退出了,队列才是真正的稳定。

这些都是中间状态。

规律:

1  每个节点只受后面节点影响

2  prev只有自己修改,没有多线程问题

3  status正常的节点的next受到后面一个真正正常调整方法和多个异常节点调整方法修改指向后面真正正常节点,

4  Status异常的节点的next只有自己修改

5  status正常的节点的status受到后面一个真正正常和多个异常修改=-1。Status异常的节点的status只有自己修改=1

再看几张图:

如果多线程同时修改同一个对象的同一个属性,一个直接赋值一个使用cas赋值(并且CAS只赋值一次)当冲突时候,直接赋值的优先级最大,cas赋值的失败了就算了让步给直接赋值的。

AQS1---走向稳定态的更多相关文章

  1. 一种全新的MEMS开关——高性能、快速、低能耗以及双稳态

    这种开关最早由申军教授和研究生阮梅春发明,研究生埃里克·朗格卢瓦在简化结构和缩小尺寸上作了探索,黄志林用相同原理做出了MEMS光学镜子开关,曹志良改变设计.材料和工艺后制作出了能同步开关的矩阵.这种M ...

  2. 2017-11-4—稳态和暂态/瞬态(对运放积分电路的思考)[待仿真]

    先直接截图了,暂态或者说瞬态都是暂时的状态,是从一个稳定态到另一个稳定态的过程. 之所以要了解这个概念是因为对于使用运放搭建的模拟PID有很多的疑惑,比如负反馈没有电阻满不满足"虚短&quo ...

  3. 编写高质量代码:改善Java程序的151个建议(第1章:JAVA开发中通用的方法和准则___建议16~20)

    建议16:易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP,Ruby,Groovy.Javascript等,这些入侵者都有一个共同特征:全是同一类语言-----脚本语言,它 ...

  4. Android微信智能心跳方案 (转)

    原创 2015-08-17 phoenix WeMobileDev 前言:在13年11月中旬时,因为基础组件组人手紧张,Leo安排我和春哥去广州轮岗支援.刚到广州的时候,Ray让我和春哥对Line和W ...

  5. Web服务及http协议

    HTTP:HyperText Transfer Protocol--超文本传输协议 超链接:能够在文档之间跳转的文本 早起的Web:仅仅是能够实现在文档之间跳转的一种协议 http/0.9:仅支持纯文 ...

  6. I2C总线协议的简要说明

    为了快速的了解I2C总线协议,此处采用另类的方式进行说明. 倘若你和另外一个人只能通过一个开关加灯泡的装置在不同的两个房间进行交流,以下是很简单能说明的一个模型: 你的房间有一个开关,另外一间房间有一 ...

  7. Java性能优化权威指南-读书笔记(五)-JVM性能调优-吞吐量

    吞吐量是指,应用程序的TPS: 每秒多少次事务,QPS: 每秒多少次查询等性能指标. 吞吐量调优就是减少垃圾收集器消耗的CPU周期数,从而将更多的CPU周期用于执行应用程序. CMS吞吐调优 CMS包 ...

  8. [改善Java代码]不要只替换一个类

    建议20: 不要只替换一个类 我们经常在系统中定义一个常量接口(或常量类),以囊括系统中所涉及的常量,从而简化代码,方便开发,在很多的开源项目中已采用了类似的方法,比如在Struts2中,org.ap ...

  9. SSD -----TLC MLC SLC

    SLC缓存什么鬼?TLC评测造假要持续多久 2016.5.5来源:中关村在线 TLC的廉价真的将SSD引入了全面普及的高速公路上,谈到TLC我们更多的理解是TLC的P/E(Program/Erase ...

随机推荐

  1. android版本对应表

    API Level 最初Android版本 Linux内核版本 首次发布日期 后续Android版本 28 9 Unknown 2018-07-02(Beta 3) - 27 8.1 4.10 201 ...

  2. 纯C语言实现线性表

    #include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 typedef int ElemType; typedef ...

  3. English--辅音

    English|辅音 英语中的辅音,按照发音的松紧,唇形舌位,划分为七大类.需要好好地体会具体的发音部位与口型. 前言 目前所有的文章思想格式都是:知识+情感. 知识:对于所有的知识点的描述.力求不含 ...

  4. 实验吧——加了料的报错注入(exp报错注入)

    题目地址:http://ctf5.shiyanbar.com/web/baocuo/index.php 先查看页面源码得到提示知道了后台执行的sql语句,很常规的查询 测试了一个报错函数发现如下回显, ...

  5. 渗透技巧——导出Chrome浏览器中保存的密码

    0x00 前言 在后渗透阶段,获得权限后需要搜集目标系统的信息.信息越全面,越有助于进一步的渗透.对于Windows系统,用户浏览器往往包含有价值的信息. 在之前的文章<本地密码查看工具LaZa ...

  6. uni-app常用 HTML5+APP 设置

    1.锁定屏幕方向 锁定屏幕方向后屏幕只能按锁定的屏幕方向显示,关闭当前页面后仍然有效. 可再次调用此方法修改屏幕锁定方向或调用 unlockOrientation() 方法恢复到应用的默认值. 锁定屏 ...

  7. 锁、分布式锁、无锁实战全局性ID

    1.为什么要使用锁 当发生并发时,会产生多线程争夺一个资源,为保证资源的唯一性. JVM锁:对象锁,死锁,重入锁,公平锁,偏向锁 分布式锁:数据库 nosql .zookeeper 面试题:如何排查死 ...

  8. Linux从入门到精通总结(非原创)

    文章大纲 一.课程内容总结二.课程学习地址三.学习资料下载四.参考文章 一.课程内容总结   二.课程学习地址 第一天:https://www.cnblogs.com/WUXIAOCHANG/p/10 ...

  9. spoon数据转换中文乱码(kettle)

    (1) 查看mysql数据库是否为utf8(status) (2) 设置spoon (3) 文本打开spoon.bat,找到set OPT=%OPT% %PENTAHO_DI_JAVA_OPTIONS ...

  10. flask项目结构

    project/ app/ # 整个程序的包目录 static/ # 静态资源文件 js/ # JS脚本 css/ # 样式表 img/ # 图片 favicon.ico # 网站图标 templat ...