【AQS 深入理解】 hasQueuedPredecessors() 理解

AQS hasQueuedPredecessors() 理解

都说理解了AQS就理解了锁的机制 那我就一个一个方法来吧~~~
【AQS 深入理解】 hasQueuedPredecessors() 理解_第1张图片

在java的 AQS中有这样一个方法 用于检测该链表有没有前面排队的节点
因为队列先进先出,即表示是否有线程等待获取锁的时间比当前线程长

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;
        return h != t &&
            ((s = h.next) == null || s.thread != Thread.currentThread());
    }

这里有个前提 排第二的线程是有条件去争取锁的 排第一的线程可能已经被锁占用 第二可以尝试去争取
下文的 next 表示 该节点的下一个节点

返回false == 前面无节点或空

h!=t 为 false

  • 也就表示队列只有一个元素 或为空 由于&&符号前部分false整体false 直接返回false

当前线程: 这种情况下我只会是第一个或者加入成为第二个~~~

h!=t 为 true ((s = h.next) == null || s.thread != Thread.currentThread())为false

  1. h!=t 代表了队列必为两个以上元素 并且 前两个不相同
  2. (s= h.next )== null 为false 表示 第二个元素不为空
  3. s.thread != Thread.currentThread() 表示 第二个元素已经是当前线程

综上 没有啥可以阻挡我获取锁 返回false

返回true == 排在了后面

h!=t 为 true

  • 确保了队列必为两个以上元素 并且 前两个不相同

((s = h.next) == null || s.thread != Thread.currentThread()) 只要有一个条件为true即可

  • 判断这个的时候说明已经有两个节点 并且起码有一个不为null 因为&&符号前面为true才会判断后面的
  • (s = h.next) == null 排老二的节点为null 不判断后面 否则老二节点不为空, 判断老二节点线程是否为当前线程
  • s.thread != Thread.currentThread() 老二的线程不是当前线程

当前线程 : 既然我是null 或者 我不是老二 那我也没啥必要获取锁 说明我还排在后面

个人代码理解 如有不对 欢迎指正!!!
如果给你提供了帮助十分荣幸~~~

你可能感兴趣的:(并发编程,JDK源码)