final boolean acquireQueued(final Node node, int arg) { boolean failed = true; try { boolean interrupted = false; for (;;) { final Node p = node.predecessor(); if (p == head && tryAcquire(arg)) {//这个地方是获取锁 setHead(node); p.next = null; // help GC failed = false; return interrupted; } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; } } finally { if (failed) cancelAcquire(node); } }
我们知道 AQS 有一个等待队列存放 因获取不到锁而阻塞的线程节点。
从上面的 实现中我们也看到 当锁被释放的时候 唤醒下一个节点线程的规则是 获取 head 节点的 next 节点作为下一个要被唤醒的节点,然后让这个节点尝试获取锁,也就是 if (p == head && tryAcquire(arg)) 。 判断当前节点的前屈是否是 head,如果是就尝试获取锁。当 if 执行成功的时候就会退出 for 循环
问题: ( 1 ) for 死循环仅有一种退出方式(上面提到的 )吗?
( 2 )我们不是说 ReentrantLock 等待可中断吗? 但是从 for 死循环中 我们看到即使你 中断了 也退出不 for 循环吧?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.