AQS独占锁获取流程
2019-06-25 15:43:48 7 举报
AQS独占锁获取流程
作者其他创作
大纲/内容
说明是重入了,需要操作:state=state+1setState(nextc);返回true,获得锁
分支3
next waiter
自旋方式获取锁或者进去挂起线程
这个方法返回 false,那么会再走一次 for 循序, 然后再次进来此方法,此时会从分支2返回 设置前驱结点的waitStatus
开始
next
current == getExclusiveOwnerThread()?
说明 pred==null(队列是空的) 或者 CAS失败(有线程在竞争入队)
head
addWaiter 的判断语句
获取锁失败,span style=\"font-size: inherit;\
分支2
wait status
返回当前节点node
Node t = tail;
获得锁
这个方法返回 false,那么会再走一次 for 循序, 然后再次进来此方法,此时会从分支1返回 true
p == head && tryAcquire(arg)
true
队列为空初始化头节点并执行(tail=head)compareAndSetHead(new Node())tail = head
false
点
自选获取锁:如果当前节点为为阻塞队列第一个,则尝试获取,如果不是第一个,则开始线程挂起相关操作
执行addWaiter(Node.EXCLUSIVE)
prev
ws=0&&ws!=1
当前线程执行挂起操作执行parkAndCheckInterrupt
自旋
else
pred != null?
自旋的方式入队 enq(node)
分支1
reentrantLock.lock()
AQS
调用
FairSync.tryAcquire(int acquires)
c == 0?
tail
执行外层acquireQueued(Node,arg)
thread
此时此刻没有线程持有锁setExclusiveOwnerThread(current)设置当前线程为持有线程,返回true,获得锁
这个套在无限循环里,head初始化失败就重新初始化,将当前线程排到队尾,有线程竞争的话排不上重复排
线程包装成node同时进入到队列中最后面去并返回当前节点Node.EXCLUSIVE,代表独占模式addWaiter(Node mode)
t == null?
返回
state
CAS操作,将当前线程排到队尾,node.prev = t
结束
setHead(node)当前节点设置为head
Node
ws=Node.SIGNAL(-1)
队列不为空将当前的队尾节点设置为自己的前驱
exclusiveOwnerThread
FairSync.lock()
用CAS将前驱节点的waitStatus设置为Node.SIGNAL(也就是-1)
0 条评论
回复 删除
下一页