AQS加锁流程图
2020-11-11 21:46:43 0 举报
超级详细AQS底层流程分析 球赞 评论交流
作者其他创作
大纲/内容
aqs 的成员变量1表示已有其它线程接获取锁
AQS类
state=1
T2 变为新的头thread=null地址 = 690
T1.lock
T2thread=t2地址 = 690waitStatus=0
tail
T1
new Node() 地址=713这个节点就是是头节点waitStatus =0thread = null
pred.next = node; node是t3
settHead(node)此时node是t2 head = node;node.thread = null;node.prev = null;
T2.lock
AQS
线程 thread1
head
Node head = nullNode tail = nullexclusiveOwnerThread ==
t2被叫醒此时t2加锁成功
T3thread=t3waitStatus=0T3.next = null
Node pred = tail;if (pred != null) 返回false进入enq方法 参数 t2线程node
waitStatus = -1
t.next = node;node 是t2
第一次循环 if (t == null) 为true 设置头节点
node.prev = t ; 此时t就是尾 而此时尾的值就是头
公平锁加锁时会判断自己是否需要排队,与非公平锁区别在于多调用了下面的一个方法
node.prev = pred; 此时 pred 就是尾节点 而尾节点 指向的又是t2 所以这个时候 相当于 t3 的钱一个节点指向t2
pred.next = node; 这里node是t3 t2.next
exclusiveOwnerThread ==
改变T2的waitStatus的状态
tail=head
情况二: 当 h!=t 为 true (s=h.next)== null 返回true 场景 : 有一个线程正在执行初始化队列的操作了,介于 enq() 方法的compareANdSetHead(new Node()) 与tail之间 这个时候尾是空 头已经有值了 情况三: s.thread != Thread.currentThread() 当 当前线程是第二个节点的时候,这2个值是相等的,这个时候返回false 整个方法返回false 也就无需排队
t2
T3.prex
aqs队列头
断开 p.next = null; p就是前head
setExclusiveOwnerThread(current);
T3thread=t3waitStatus=0
// AQS 测试代码 流程加锁 入队 解锁 出队 流程 本次测试使用ReentrantLock 的非公平锁
state=0
t.next = node;
int c = getState() - releases;setState(c)
t2线程加锁失败 进入addWaiter方法
aqs队列尾
T2thread=t2地址 = 690
node.prev = t node 是t2
setExclusiveOwnerThread(null)
new Node() 地址=713这个节点就是是头节点waitStatus = -1thread = null
t2加锁过程
线程 thread3
null
node.prev = t
new Node()这个节点是头节点
线程 thread2
t.next = node; node 是t2 head.next
new Node() 地址=713这个节点就是是头节点
t1 线程占着锁,state=1 cas失败走 acquire 方法
node.prev = t node=t2
new Node() 地址=713这个节点就是是头节点waitStatus=0
T1线程释放锁T1.unlock
执行完成后队列 主要是将T2的前一个节点的 waitStatus 值改为-1
t1.rellease tryReleads() 和 unparkSuccessor() 方法
addWaiter 方法 返回t2线程node 690,将t2 线程park掉 然后醒来再继续执行 返回后再调用 acquireQueued()方法
T3
T3.lock
t1 end
aqs 的成员变量0表示可以直接获取锁
//返回true 说明有队列需要排队 返回false 说明没有队列 无需排队 public final boolean hasQueuedPredecessors() { // The correctness of this depends on head being initialized // before tail and on head.next being accurate if the current // thread is first in queue. Node t = tail; // 队列尾部 Node h = head;//队列头部 Node s;//首次进入,aqs队列还没初始化 t和 h 都为空 直接返回false 不需要排队 return h != t &&// 头和尾 不等,说明有线程再排队 s.thread == Thread.currentThread() 说明当前线程是排在队首的线程 可以算没有队列排队能直接获取锁 ((s = h.next) == null || s.thread != Thread.currentThread()); }
T2
0 条评论
回复 删除
下一页