阳哥AQS
2022-08-23 13:49:25 1 举报
AQS 源码解析
作者其他创作
大纲/内容
true
acquireQueued
false
Lock
pred != null
Reentrantlock
返回false
acquireQueued方法详解
sync.lock();
返回node
成功获取到锁,设置持有线程为当前线程 返回
false 执行步骤2
false 再次刷新
阻塞结束
这个方法。接收两个Node对象参数2 是准备执行park操作的节点node1是其前辈节点pred
设置pred.waitStatus=-1
parkAndCheckInterrupt线程进入阻塞状态
两种情况,会导致阻塞结束1 持有锁的线程,释放锁只会,将这个线程unpark了,此时该线程。一定排在队列的对头(不包含head节点)2 线程被interrupt 了,在外部interrupt这个线程。不是抛出interruptException异常 这一点和sleep wait阻塞不一样
p==head表示查询node 是不是第一个排队的
返回Node
尝试获取锁获取不到就排队(阻塞当前线程)
>0,只能是==1 即CANCELLED.表示node 的前辈节点,已经取消了 ,此时将链表关系重新维护下,即将前辈节点移除队列
cas获取锁
sync继承了AbstractQueuedSynchronizer
FairSync#lock
执行排队
队列尚未初始化,调用enq方法该方法生成一个空的Node 对象 new Node() 右边粉色部分,插入aqs队列头部,然后将参数Node 作为后继节点,插入完毕队列如右图
这个队列表示,在线程c进入之前,已经有一个线程在排队获取锁了
返回true
执行park逻辑
队列已经初始化,加入到队列尾部,加入后队列可能如下
公平锁
NonfairSync#lock
pred.waitStatus>0
这部分是node加入队列后的处理逻辑,这里会有一次自旋,尝试获取锁,获取不到,才会调用parh ,阻塞自己
true 执行步骤1
tryAcquire
addWaiter
再次循环判断
注意。这里设置的是pred节点,而不是node节点的waitstate -1表示节点处于阻塞状态了为何每个节点进入该方法后,修改是上个节点的waitstate 不是自己的因为线程调用park后,无法设置自己的这一个状态,若在park前不存在一致性问题。所以每个节点的waitstate ,在后继节点加入时候设置
acquire(1);
enq(node); ②
acquireQueued返回,表示线程获取到锁,线程返回 ,执行加锁结束
shouldParkAfterFailedAcquire方法详解
enq方法
非公平锁
表示获取到锁1 node设置为头节点2释放之前的头节点,这个逻辑执行完成后。node节点就不会再排队了(获取到锁的队列,不会在排队队列中)
abstract void lock();
addWaiter详解
pred.waitStatus == Node.SIGNAL
收藏
0 条评论
下一页