AQS1---走向稳定态
AQS的思想(稳定思想):即使确定了正常节点,这个节点也可能下一秒异常,即使找到了正常节点,这个节点可能只是异常status=0/-1的节点,这些都不要紧,都只是在自己旋转‘生命周期’里面和自己所看到的 最大可能的保证队列的稳定状态,如果判断错了,其他节点会帮着处理直到队列真正的稳定。
AQS的思想(出队思想):通过head=-1出队,head=0出队失败(外部线程不会再次调用head出队)后面节点就要自行出队。(unlock方法会被没有进入队列抢到了锁的线程调用,队列中获取到锁的线程执行完之后也会调用)
队列走向稳定时候,是多个节点线程在调节某一个节点,并且还有一个出队的线程在调节head。
ReentrantLock#AQS是一个FIFO的队列,通过head来出队,通过taill入队。
- 队列稳定状态
- 队列处于没有稳定的中间态
- 队列稳定时候出队
- 队列没有稳定时候出队。
节点状态分为:正常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---走向稳定态的更多相关文章
- 一种全新的MEMS开关——高性能、快速、低能耗以及双稳态
这种开关最早由申军教授和研究生阮梅春发明,研究生埃里克·朗格卢瓦在简化结构和缩小尺寸上作了探索,黄志林用相同原理做出了MEMS光学镜子开关,曹志良改变设计.材料和工艺后制作出了能同步开关的矩阵.这种M ...
- 2017-11-4—稳态和暂态/瞬态(对运放积分电路的思考)[待仿真]
先直接截图了,暂态或者说瞬态都是暂时的状态,是从一个稳定态到另一个稳定态的过程. 之所以要了解这个概念是因为对于使用运放搭建的模拟PID有很多的疑惑,比如负反馈没有电阻满不满足"虚短&quo ...
- 编写高质量代码:改善Java程序的151个建议(第1章:JAVA开发中通用的方法和准则___建议16~20)
建议16:易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP,Ruby,Groovy.Javascript等,这些入侵者都有一个共同特征:全是同一类语言-----脚本语言,它 ...
- Android微信智能心跳方案 (转)
原创 2015-08-17 phoenix WeMobileDev 前言:在13年11月中旬时,因为基础组件组人手紧张,Leo安排我和春哥去广州轮岗支援.刚到广州的时候,Ray让我和春哥对Line和W ...
- Web服务及http协议
HTTP:HyperText Transfer Protocol--超文本传输协议 超链接:能够在文档之间跳转的文本 早起的Web:仅仅是能够实现在文档之间跳转的一种协议 http/0.9:仅支持纯文 ...
- I2C总线协议的简要说明
为了快速的了解I2C总线协议,此处采用另类的方式进行说明. 倘若你和另外一个人只能通过一个开关加灯泡的装置在不同的两个房间进行交流,以下是很简单能说明的一个模型: 你的房间有一个开关,另外一间房间有一 ...
- Java性能优化权威指南-读书笔记(五)-JVM性能调优-吞吐量
吞吐量是指,应用程序的TPS: 每秒多少次事务,QPS: 每秒多少次查询等性能指标. 吞吐量调优就是减少垃圾收集器消耗的CPU周期数,从而将更多的CPU周期用于执行应用程序. CMS吞吐调优 CMS包 ...
- [改善Java代码]不要只替换一个类
建议20: 不要只替换一个类 我们经常在系统中定义一个常量接口(或常量类),以囊括系统中所涉及的常量,从而简化代码,方便开发,在很多的开源项目中已采用了类似的方法,比如在Struts2中,org.ap ...
- SSD -----TLC MLC SLC
SLC缓存什么鬼?TLC评测造假要持续多久 2016.5.5来源:中关村在线 TLC的廉价真的将SSD引入了全面普及的高速公路上,谈到TLC我们更多的理解是TLC的P/E(Program/Erase ...
随机推荐
- 深浅赋值+orm操作+Django-admin简单配置
知识点 深浅copy 浅值深id orm操作 ManyToManyField 虚拟字段 告诉Django orm 自动帮你创建第三张表 查询的时候可以借助该字段跨表 外键属性可赋值外联对象 Model ...
- bash信号捕捉
我们ping一个主机,然后按下ctrl+c那么就会终止这个ping动作,如下图: 可是如果使用一个循环来逐个ping不同主机,你再按下ctrl+c就会发现停不下来,直到循环完成,如下图: #!/bin ...
- 在verilog中使用格雷码
格雷码的一些知识: https://baike.baidu.com/item/%E6%A0%BC%E9%9B%B7%E7%A0%81/6510858?fr=aladdin 绿色框起来的是0--15的格 ...
- A MacFUSE-Based Process File System for Mac OS X
referer: http://osxbook.com/book/bonus/chapter11/procfs/ Processes as Files The process file system ...
- Git的下载安装
下载地址:https://git-scm.com/download/win 命令: git add ... ---将资源放到缓存区域 git commit -m "提交说明" ...
- LDA-作为线性判别 降维 推导
LDA 降维原理 前面对 LDA 作为作为分类器 有详细推导, 其核心就是 贝叶斯公式, 已知全概率, 求(条件概率)最大先验概率, 类似的问题. 而 LDA 如果作为 降维 的原理是: a. 将带上 ...
- ssh免密登录(公钥私钥)指令
1.在.ssh目录中执行ssh-keygen -t rsa命令生成两个秘钥,公钥(id_rsa.pub)和私钥(id_rsa) 2.ssh-copy-id -i id_rsa.pub 对方用户名@对方 ...
- python之线程和进程(并发编程)
python的GIL In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native ...
- np.random 系列函数
1 random() # 产生区间 [0, 1) 均匀分布的浮点数样本值 np.random.seed(42) 2 rand(d0, d1, ..., dn) # 产生区间 [0, 1) 均 ...
- django+sqlite进行web开发(二)
模板 前面的例子中,我们是直接将HTML写在了Python代码中,这种写法并不可取.我们需要使用模板技术将页面设计和Python代码分离. 模板通常用于产生HTML,但是Django的模板也能产生任何 ...