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. 微服务架构 ------ Dockerfile定制镜像

    Docker容器不仅仅是运行原生的容器,而是把我们的具体的项目能够布置到容器上面去,这就是Docker定制镜像需要做的事情.  Docker容器 = new Docker镜像  镜像相当于类,容器相当 ...

  2. 配置DirectX SDK开发环境

    创建工程 选择空工程 添加源文件 添加DirectX SDK测试程序 属性配置 添加头文件和库文件路径 D:\Microsoft DirectX SDK (February 2010)\Include ...

  3. Android ListView显示不同样式的item

    先look图 我们再使用listview时,listview的item大多时候都是一种样式,在很多app中也很常见,但有时候根据需求,可能数据的数量不一样,同个类型的数据显示的位置不同,亦或者有的it ...

  4. ChengDu University Mental Health Test 需求分析文档

    ChengDu University Mental Health Website 需求分析文档 V4.0 编制人:刘雷,黄凯 日期:2019/4/28 版本修订历史记录: 版本 日期 修改内容 作者 ...

  5. pdf的使用遇到的问题

    http://blog.csdn.net/atluckstar/article/details/77688972 回答网友提问  2015-7-28 因为好多人问能不能显示中文的问题,我总结大致分为两 ...

  6. fiddler深入学习

    参考:https://www.cnblogs.com/zhizhiyin/p/6807649.html http://blog.chinaunix.net/uid-27105712-id-373882 ...

  7. 《MySQL性能优化篇》阅读笔记

    建表的时候,不要用null赋默认值,如:字符串的设置'',数据类型的设为0,不要将null设为默认值. 在MySQL中没有 full [outer] join,用union代替 各种 JOIN SQL ...

  8. Sublime Text2中的快捷方式及html各种标签(待完善)

    快捷方式 1.xhtml+tab 2.自动补全标签 Alt + .  补全标签 标签 1.<p>段落标签 ,前后换行 <h1.2.3.4.5>标题标签 h1最大,一级标题 2. ...

  9. Scikit-learn Preprocessing 预处理

    本文主要是对照scikit-learn的preprocessing章节结合代码简单的回顾下预处理技术的几种方法,主要包括标准化.数据最大最小缩放处理.正则化.特征二值化和数据缺失值处理. 数学基础 均 ...

  10. 【java】new Date什么样

    Thu Nov 21 10:39:40 GMT+08:00 2019 getDate() 从 Date 对象返回一个月中的某一天 (1 ~ 31).getDay() 从 Date 对象返回一周中的某一 ...