标签:shouldParkAfterFailedAcquire 系列 AQS waitStatus T2 源码 线程 进行 waitState
AQS中存在设置waitState状态的方法 shouldParkAfterFailedAcquire , 根据问题反推其设计的原因
shouldParkAfterFailedAcquire源码如下
以ReentrantLock为例子
问题
ReentrantLock进行unlock时,源码如下
AQS根据waitStatus进行队列中线程的唤醒,waitStatus初始值为0,
在ReentrantLock中,若waitStatus为-1,则标识后续的一个线程是需要被唤醒的线程
假设一种场景,两个线程并发执行,第一个线程T1先执行,获取到了锁,第二个线程T2后执行,T2执行到了shouldParkAfterFailedAcquire时,cpu调度时间用完,停止运行;T1进行unLock
根据unLock源码,T1直接执行完,不会进行unparkSuccessor(h),也就没有对T2进行unpark。
此时若T2再次获得执行机会,进行shouldParkAfterFailedAcquire ,则设置前一个节点waitStatus为-1,及运行compareAndSetWaitStatus ,最终返回false
再看 shouldParkAfterFailedAcquire被调用的地方
此时返回false,循环继续,发现T2的前一个节点是头节点,进行tryAcquire。
若是公平锁,必然会获取锁成功。
若是非公平锁,存在获取锁失败的情况,再次调用shouldParkAfterFailedAcquire,返回true,进行调用 parkAndCheckInterrupt,及进行park操作
综述,shouldParkAfterFailedAcquire在compareAndSetWaitStatus为什么返回false,就比较明朗了,要是获取到锁的线程,没有对head后面的线程进行unpark操作,则该线程通过自旋,自己再次尝试获取锁
标签:shouldParkAfterFailedAcquire,系列,AQS,waitStatus,T2,源码,线程,进行,waitState 来源: https://www.cnblogs.com/sxrtb/p/16585159.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。