AQS(释放资源 4)--队列同步器
1.unparkSuccessor(Node)
该方法主要用于唤醒等待队列中的下一个阻塞线程。
private void unparkSuccessor(Node node) {
// 获取当前节点的ws值
int ws = node.waitStatus;
// 将当前节点的ws值置0
if (ws < 0)
compareAndSetWaitStatus(node, ws, 0);
Node s = node.next;
// 若后继节点为null或者其ws值大于0(放弃状态),则从等待队列的尾节点从后往前搜索,
// 搜索到等待队列中最靠前的ws值非正且非null的节点
if (s == null || s.waitStatus > 0) {
s = null;
for (Node t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0) s = t;
}
// 如果后继节点非null,则唤醒该后继节点持有的线程
if (s != null)
LockSupport.unpark(s.thread);
}
后继节点的阻塞线程被唤醒后,就进入到acquireQueued()的
if (p == head && tryAcquire(arg))的判断中,
此时被唤醒的线程将尝试获取资源。
当然,如果被唤醒的线程所在节点的前继节点不是头结点,
经过shouldParkAfterFailedAcquire的调整,
也会移动到等待队列的前面,直到其前继节点为头结点。
讲解完独占模式下资源的acquire/release过程,下面开始讲解共享模式下,
线程如何完成资源的获取和共享。
学习来源:https://www.jianshu.com/p/0f876ead2846

浙公网安备 33010602011771号