从ReentrantLock实现看AQS原理
2021-05-23 19:26:25 1 举报
AQS是一种提供了原子式管理同步状态、阻塞和唤醒线程功能以及队列模型的简单框架。这个图通过ReentrantLock的基本特性和ReentrantLock与AQS的关联,来深入解读AQS相关独占锁的知识点,同时采取问答的模式来帮助大家理解AQS
作者其他创作
大纲/内容
获取锁成功返回
shouldParkAfterFailedAcquire详解
设置前节点为-1,表示为阻塞状态。1、检测到0后,一定要设置成SIGNAL的原因:设置前驱状态为SIGNAL,以便当前线程阻塞后,前驱能根据SIGNAL状态来唤醒自己。(具体看章节释放锁后,唤醒head后继的条件)2、设置成SIGNAL后会返回false的原因:返回false后,下一次循环开始,会重新获取node的前驱,前驱如果就是head,那么还会重新尝试获取锁。这次重新尝试是有必要的,某些场景下,重新尝试获取锁会成功。
true
tryAcquire
false
表示前节点为取消状态,将前节点移出队列
返回false
返回ture
从ReentrantLock的实现看AQS的原理及应用喜欢的朋友点赞支持下
shouldParkAfterFailedAcquire
两种情况阻塞结束:1、持有锁的线程,释放锁以后,将这个线程LockSupport.unpark()。此时该线程一定排在head的下一个节点2、线程被interrupt了
NonFairSync#lock()
addWaiter
acquireQueued
head
队列结构
acquire(1)
p==head
非公平锁
acqurireQueued详解
headwaitState:0
CAS设置前节点waitState为-1
LockSupport.park()
next
表示获取到锁:1、node设置为头节点2、释放之前的头节点,重整队列
线程未获取到锁
false再次刷新
阻塞结束
将当前线程封装成Node对象未初始化: enq会初始化空节点head,将node指向head下一个节点已经初始化: node加入队列对尾
CAS获取锁
lock()
addWaiter详解
parkAndCheckInterrupt()
aqs队列(链表)
前节点waitState是否为-1
公平锁
node
ReetrantLock
FairSync#lock()
再次循环判断
前节点waitState>0
abstract void lock()
prev
tail
0 条评论
回复 删除
下一页