AbstractQueuedSynchronizer源码剖析(三)- 响应中断的独占锁
来源:互联网 发布:全国房地产数据服务商 编辑:程序博客网 时间:2024/05/16 14:03
1、AbstactQueuedSynchronizer的基本数据结构
1.1 AbstractQueuedSynchronizer的等待队列是CLH队列的变种,CLH队列通常用于自旋锁,AQS中的CLH可以简单的理解为“等待锁的线程队列”。
1.3 一条线程所在节点如果它处于队列头的下一个节点,那么它会尝试去acquire。因为头节点是一个dummy节点,也就是说头节点不持有任何线程。所以,一条线程所在节点如果它处于队列头节点的下一个节点,那么他会尝试去acquire,但是并不保证成功。
1.4 要进入队列,你只需要自动将它拼接在队列尾部即可;如果获取了锁,你只需要设置header字段即可。
2、在“响应中断的独占锁”模式下AbstractQueuedSynchronizer供子类实现的方法
3、在“响应中断的独占锁”模式下AbstractQueuedSynchronizer获取锁的实现流程
如果尾节点为空,即当前数据结构中没有节点,那么new一个不带任何状态的Node作为头节点,并且将head赋值给tail。如果尾节点不为空,那么并发下使用CAS算法将当前Node追加成为尾节点,由于是一个for(;;)循环,因此所有没有成功acquire的Node最终都会被追加到数据结构中。
4、在“响应中断的独占锁”模式下AbstractQueuedSynchronizer释放锁流程
逻辑并不复杂。它调用tryRelease来释放资源。有一点需要注意的是,它是根据tryRelease的返回值来判断该线程是否已经完成释放掉资源了!所以自定义同步器在设计tryRelease的时候要明确这一点!!跟tryAcquire一样,这个方法是需要独占模式的自定义同步器去实现的。正常来说,tryRelease都会成功的,因为这是独占模式,该线程来释放资源,那么它肯定已经拿到独占资源了,直接减掉相应量的资源即可(state-=arg),也不需要考虑线程安全的问题。但要注意它的返回值,上面已经提到了,release是根据tryRelease的返回值来判断该线程是否已经完成释放掉资源了!所以自定义同步器在实现时,如果已经彻底释放资源(state=0),要返回true,否则返回false。如果没有彻底释放资源,也就是出现了重入的情况,需要多次释放。如果释放成功了,我们就需要唤醒head节点的下一个节点所持有的线程。基本逻辑如下:
1. 首先拿到head节点,判断head节点不等于null,并且head节点的waitStatus是不等于0的话,就去唤醒head节点的下一个节点所持有的线程。
2. 调用unparkSuccessor(Node node)方法唤醒head节点的下一个节点所持有的线程。这个函数并不复杂。一句话概括:用unpark()唤醒等待队列中最前边的那个未放弃的线程,这里我们也用s来表示吧。此时,再和acquireQueued()联系起来,s被唤醒后,进入if (p == head && tryAcquire(arg))的判断(即使p!=head也没关系,它会再进入shouldParkAfterFailedAcquire()寻找一个安全点。这里既然s已经是等待队列中最前边的那个未放弃的线程了,那么通过shouldParkAfterFailedAcquire()的调整,s也必然会跑到head的next结点,下一次自旋p==head就成立啦),然后s把自己设置成head标杆结点,表示自己已经获取到资源了,acquire()也返回了!
- AbstractQueuedSynchronizer源码剖析(三)- 响应中断的独占锁
- AbstractQueuedSynchronizer源码剖析(二)- 不响应中断的独占锁
- AbstractQueuedSynchronizer源码剖析(五)- 响应中断的共享锁
- AbstractQueuedSynchronizer源码剖析(四)- 不响应中断的共享锁
- AbstractQueuedSynchronizer的衍生品ReentrantLock(七)- 不响应中断的独占锁
- Java并发源码剖析(一)——AbstractQueuedSynchronizer独占模式
- java AbstractQueuedSynchronizer的实现分析(独占锁)
- AbstractQueuedSynchronizer:独占锁
- AbstractQueuedSynchronizer源码分析一(独占锁部分,公平非公平)
- AbstractQueuedSynchronizer深度学习(独占锁)
- 深入分析AbstractQueuedSynchronizer独占锁的实现原理:ReentranLock
- AbstractQueuedSynchronizer实现源码解析(三)
- AbstractQueuedSynchronizer源码剖析(一)- 从抽象和接口说起
- 关于AQS(AbstractQueuedSynchronizer)中对中断的应用
- jdk-AbstractQueuedSynchronizer(三)
- 深入理解AbstractQueuedSynchronizer(三)
- Azureus源码剖析(三)
- chromium源码剖析(三)
- 使用npm利用vue-cli搭建vue环境
- UVA
- Linux(C/C++)下的文件操作open、fopen与freopen
- P01: 01背包问题
- JS小结-XHTML与HTML5
- AbstractQueuedSynchronizer源码剖析(三)- 响应中断的独占锁
- 二维数组练习
- 面试时自我介绍怎么说,一个程序媛找了半年工作之后,写下了这段文字:
- 洛谷1182 数列分段Section II
- 数据结构思维 第二章 算法分析
- 51nod 1137矩阵乘法【矩阵】
- leetcode-648. Replace Words
- 推广中文域名的重要性和建议
- 有趣的Java-J03