ReentrantLock
2019-09-18 10:32:54 0 举报
源码流程图模板
作者其他创作
大纲/内容
当前节点时候是 head.next
N
CAS 设置AQS的状态 status : 0->1
1、AQS 独占模式和共享模式的区别?2、AQS 是JUC的基石,那么它自己做了什么,又把那些事情给其实现类做?3. CAS 是怎么操作的4. ReentrantLock 的公平锁和非公平锁的本质是什么
说明锁重入了,直接返回了
Y
调用 AQS:parkAndCheckInterrupt(),调用LockSupport.park(this); 挂起当前线程
表示AQS 中的方法
调用 AQS : acquire(1)这里开始代表存在其他线程竞争
1、AQS 把怎么表示当前线程拿到锁交给了其实现类,比如ReentrantLock 的tryAcquire 和 CAS 设置 status状态。把对同步队列的排队、挂起等操作封装到自己内部
调用ReentrantLock :NonfairSync:tryAcquire
当前线程持有了锁,返回继续执行同步代码块
调用ReentrantLock :NonfairSync:lock
CAS 是否成功
线程调用ReentrantLock: unlock()
表示线程挂起
status为0
调用 AQS : addWaiter(),创建本线程的节点,自旋添加到同步队列尾部,这里代表已经尝试过加锁并且失败了,需要到队列排队了
表示ReentrantLock 代码块的出口
为什么是 head.next?因为 head 是代表已经执行过的线程,已经获取过同步状态,所以每个线程只需要检查自己是否为 head.next
tryAcquire(1)
调用ReentrantLock :FairSync:tryAcquire
挂起
调用 AQS : acquireQueued()
恢复
设置当前结点为 head
队列中存在阻塞节点
自旋
表示ReentrantLock 代码块的入口
(0 代表了锁未被持有,1代表持有,大于1代表锁重入了)
CAS 设置AQS的状态 status : 0->1| |判断AQS是否被当前线程持有(此时代表锁重入了)
跳过那些waitStatus大于0的节点(代表超时中断的),把前置节点的waitStatus 置为 -1
调用ReentrantLock :FairSync:lock
调用 AQS : shouldParkAfterFailedAcquire(),判断当前线程用不用挂起 (block)
前置节点的waitStatus是否为-1
找到队列中最靠前的在阻塞状态的线程
LockSupport.unpark(s.thread) 恢复刮起的线程
调用 AQS : tryAcquire(1),模板方法,ReentrantLock 里面有公平锁和非公平锁两种方式
设置AQS的持有线程
判断当前节点是否有前置节点
表示 ReentrantLock 中的方法
head.next 是为空null 或者 waitStatus大于0 (被中断)
0 条评论
下一页