本文中部分源码本人暂时也尚未能理解,希望各位大佬不吝赐教,主要有以下一些问题:
1.在unparkSuccessor方法中,找到队列下一个节点并将其唤醒时,为什么从尾到头遍历
2.在acquireQueued方法中,自旋结束后的finally代码块的作用。
final boolean acquireQueued(final Node node, int arg) { boolean failed = true; //是否获取到资源 try { boolean interrupted = false; //等待过程中是否被中断 //自旋,维护等待队列中线程的执行。 for (;;) { final Node p = node.predecessor(); //获取node的前置p if (p == head && tryAcquire(arg)) { //若前置p为头结点并且重新获取锁成功 setHead(node); //设置新的头节点为node p.next = null; // help GC //取消p和链表的链接 failed = false; //获取资源未失败 return interrupted; //等待过程未被中断 } if (shouldParkAfterFailedAcquire(p, node) && //若前置节点是Node.SIGNAL状态 parkAndCheckInterrupt()) //将节点设置为Waitting状态 interrupted = true; //此时线程中断状态为true } } finally { if (failed) //如果自旋结束,那么说明failed = false已经执行了,那么这个canclAcquire方法什么情况下会执行? cancelAcquire(node); } }