AQS-hasQueuedPredecessors()解析

原文链接:https://blog.csdn.net/weixin_38106322/article/details/107154961

hasQueuedPredecessors()方法源码如下:

public final boolean hasQueuedPredecessors() {
    //读取头节点
    Node t = tail; 
   //读取尾节点
    Node h = head;
    //s是首节点h的后继节点
    Node s;
    return h != t &&
        ((s = h.next) == null || s.thread != Thread.currentThread());
}

这里先说一下hasQueuedPredecessors()方法的作用,主要是用来判断线程需不需要排队,因为队列是FIFO的,所以需要判断队列中有没有相关线程的节点已经在排队了。有则返回true表示线程需要排队,没有则返回false则表示线程无需排队。

结果一: 返回false,不需要排队

情况一: h != t返回false,那么短路与判断就会直接返回false

说明:当头节点和尾节点相等时,才会返回false。
头节点和尾节点都为null,表示队列都还是空的,甚至都没完成初始化,那么自然返回fasle,无需排队。
头节点和尾节点不为null但是相等,说明头节点和尾节点都指向一个元素,表示队列中只有一个节点,这时候自然无需排队,因为队列中的第一个节点是不参与排队的,它持有着同步状态,那么第二个进来的节点就无需排队,因为它的前继节点就是头节点,所以第二个进来的节点就是第一个能正常获取同步状态的节点,第三个节点才需要排队,等待第二个节点释放同步状态。

情况二:h != t返回true,(s = h.next) == null返回false以及s.thread !=

Thread.currentThread()返回false

说明:h != t返回true表示队列中至少有两个不同节点存在。
(s = h.next) == null返回false表示头节点是有后继节点的。
s.thread != Thread.currentThread()返回fasle表示着当前线程和后继节点的线程是相同的,那就说明已经轮到这个线程相关的节点去尝试获取同步状态了,自然无需排队,直接返回fasle。

结果二.返回true

情况一: h != t返回true,(s = h.next) == null返回true

h != t返回true表示队列中至少有两个不同节点存在。
(s = h.next) == null返回true,说明头节点之后是没有后继节点的,这情况可能发生在如下情景:有另一个线程已经执行到初始化队列的操作了,介于compareAndSetHead(new Node())与tail = head之间,如下:

这时候头节点不为null,而尾节点tail还没有被赋值,所以值为null,所以会满足h != t结果为true的判断,以及头节点的后继节点还是为null的判断,这时候可以直接返回true,表示要排队了,因为在当前线程还在做尝试获取同步状态的操作时,已经有另一个线程准备入队了,当前线程慢人一步,自然就得去排队。

情况二:h != t返回true,(s = h.next) == null返回false,s.thread !=

Thread.currentThread()返回true。

h != t返回true表示队列中至少有两个不同节点存在。
(s = h.next) == null返回false表示首节点是有后继节点的。
s.thread != Thread.currentThread()返回true表示后继节点的相关线程不是当前线程,所以首节点虽然有后继节点,但是后继节点相关的线程却不是当前线程,那当前线程自然得老老实实的去排队

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值