AQS中,独占公平锁的增加与删除
addWaiter()
增加addWaiter():1.线程打包成Node, 通过CAS方式加入队列尾部
2.获取队列尾部, 尝试加入
3.加入失败, CAS自旋, 重新获取队列尾部, 再加入, 直到成功为止(while loop, 持续加入)
aqcuirequeue()
(排队节点尝试获取锁, aqcuirequeue()):
当addWaiter()成功以后,每一个Node就要尝试着去获取锁了, 也就是acquirequeue()这个function.
1.进入whileLoop, 检查前一个Node是否为head, 并且能不能从它拿获取锁.
2a.如果成功, 让首节点.next指向null(便于GC), 把当前节点设为头节点
2b.如果失败, 被LockSupport Park,沉睡, 当前一个node释放的时候, unpark, 继续whileLoop尝试获取锁
头节点release()
从首节点的release来看怎么去给锁
0.把statue从1设置成0(释放锁)
1.拿到排队节点
2.看排队节点的waitstatus, 如果不是cancel的话就release, 否则从后往前找, 找到一个不是cancel的节点, 唤醒那个节点,
AQS和锁的全局图
图中应该是set state 0 to 1
TryAcquire中明显是一次非公平抢占操作,伴随着acquireQueued
网友评论