AQS hasQueuedPredecessors() 理解
都说理解了AQS就理解了锁的机制 那我就一个一个方法来吧~~~
在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
- h!=t 代表了队列必为两个以上元素 并且 前两个不相同
- (s= h.next )== null 为false 表示 第二个元素不为空
- 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 或者 我不是老二 那我也没啥必要获取锁 说明我还排在后面
个人代码理解 如有不对 欢迎指正!!!
如果给你提供了帮助十分荣幸~~~