Java并发之AQS源码篇

Java并发之AQS源码篇

二、完整源码

以下源码版本为JDK8。

package java.util.concurrent.locks;
import java.util.concurrent.TimeUnit;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import sun.misc.Unsafe;

/**
* 为实现依赖先进先出(FIFO)等待队列的阻塞锁和相关同步器(信号量、事件等)提供了一个框架。
* 该类被设计为大多数类型的同步器的有用基础,这些同步器依赖于单个原子int值来表示状态。
* 子类必须定义改变这种状态的受保护方法,这些方法定义了该对象被获取或释放时该状态的含义。
* 考虑到这些,这个类中的其他方法执行所有排队和阻塞机制。
* 子类可以维护其他状态字段,但是只有使用getState、setState和compareAndSetState方法操纵的自动更新的int值才会跟踪同步。
*
* 子类应该定义为非公共的内部助手类,用于实现其外围类的同步属性。
* 类AbstractQueuedSynchronizer不实现任何同步接口。
* 相反,它定义了诸如acquireInterruptibly之类的方法,具体锁和相关同步器可以在适当的时候调用这些方法来实现它们的公共方法。
*
* 该类支持默认独占模式和共享模式。当以独占模式获取时,其他线程的尝试获取无法成功。
* 多线程获取共享模式可能(但不需要)成功。这个类不“理解”这些差异,除非从机械意义上说,
* 当共享模式获取成功时,下一个等待线程(如果存在)也必须确定它是否也可以获取。在不同模式下等待的线程共享同一个FIFO队列。
* 通常,实现子类只支持这些模式中的一种,但这两种模式都可以发挥作用,例如在ReadWriteLock中。
* 仅支持独占模式或仅支持共享模式的子类不需要定义支持未使用模式的方法。
*
* 这个类定义了一个嵌套的AbstractQueuedSynchronizer.ConditionObject类,
* 它可以被支持独占模式的子类用作Condition实现,在这种模式下,isheldexexclusive方法报告是否对当前线程独占保持同步,
* 使用当前getState值调用的方法release完全释放该对象,并且在给定此保存的状态值的情况下,
* 获取最终将该对象恢复到其先前获取的状态。AbstractQueuedSynchronizer方法不会创建这样的条件,
* 所以如果不能满足此约束,就不要使用它。AbstractQueuedSynchronizer的行为。
* 当然,ConditionObject取决于其同步器实现的语义。
*
* 该类为内部队列提供了检查、检测和监视方法,也为条件对象提供了类似的方法。
* 可以根据需要使用AbstractQueuedSynchronizer为其同步机制将这些导出到类中。
*
* 该类的序列化仅存储维护状态的底层原子整数,因此反序列化的对象具有空线程队列。
* 需要可序列化性的典型子类将定义一个readObject方法,在反序列化时将其恢复到已知的初始状态。
*
* 要使用这个类作为同步器的基础,通过使用getState、setState和/或compareAndSetState检查和/或修改同步状态,
* 重新定义以下方法:
* - tryAcquire
* - tryRelease
* - tryAcquireShared
* - tryReleaseShared
* - isHeldExclusively
*
* 默认情况下,这些方法都会抛出UnsupportedOperationException。
* 这些方法的实现必须是内部线程安全的,通常应该是简短的,而不是阻塞的。
* 定义这些方法是唯一支持的使用该类的方法。所有其他方法都被声明为final,因为它们不能独立变化。
*
* 您可能还会发现从AbstractOwnableSynchronizer继承的方法对于跟踪拥有独占同步器的线程非常有用。
* 我们鼓励您使用它们——这使得监视和诊断工具能够帮助用户确定哪些线程持有锁。
*
* 尽管这个类是基于内部FIFO队列的,但它不会自动执行FIFO获取策略。排他同步的核心是:
* Acquire:
* while (!tryAcquire(arg)) {
* // 如果线程尚未排队,则进入队列;
* // 可能阻塞当前线程;
* }
*
* Release:
* if (tryRelease(arg))
* // 解除第一个排队线程的阻塞
*
* (共享模式类似,但可能涉及级联信号。)
*
* 因为获取中的检查是在排队之前调用的,所以新获取的线程可能会抢在其他被阻塞和排队的线程前面。
* 但是,如果需要,您可以定义tryAcquire和/或tryacquirered,通过内部调用一个或多个检查方法来禁用闯入,
* 从而提供公平的FIFO获取顺序。特别是,大多数公平同步器可以将tryAcquire定义为在hasqueued前
* (一个专门为公平同步器使用的方法)返回true时返回false。其他变化也是可能的。
*
* 吞吐量和可伸缩性对于默认的驳船(也称为贪心、放弃和护航回避)策略通常是最高的。
* 虽然这不能保证公平或无饥饿,但允许较早排队的线程在较晚排队的线程之前重新争用,并且每次重新争用对传入线程都有一个无偏的成功机会。
* 此外,虽然acquire不会像通常意义上那样“旋转”,但它们可能会在阻塞之前执行与其他计算穿插的tryAcquire的多次调用。
* 当独占同步只是短暂地保持时,这提供了自旋的大部分好处,而在不保持独占同步时则没有大部分缺点。
* 如果需要,您可以通过在调用之前使用“快速路径”检查来获取方法来增加这一点,可能会预先检查hasContended和/或hasQueuedThreads,以便仅在同步器可能不会被争用时才这样做。
*
* 这个类为同步提供了一个高效和可扩展的基础,部分是通过将其使用范围专化到可以依赖于int状态、获取和释放参数的同步器,
* 以及一个内部FIFO等待队列。如果这还不够,您可以使用原子类、您自己的自定义java.util.Queue类和LockSupport阻塞
* 支持从较低级别构建同步器。
*
* 使用示例
*
* 下面是一个不可重入互斥锁类,它使用值0表示未锁定状态,1表示锁定状态。
* 虽然不可重入锁并不严格要求记录当前所有者线程,但这个类还是这样做了,以便更容易监控使用情况。
* 它还支持条件,并公开了一种检测方法:
*
*
* class Mutex implements Lock, java.io.Serializable {
*
* // Our internal helper class
* private static class Sync extends AbstractQueuedSynchronizer {
* // Reports whether in locked state
* protected boolean isHeldExclusively() {
* return getState() == 1;
* }
*
* // Acquires the lock if state is zero
* public boolean tryAcquire(int acquires) {
* assert acquires == 1; // Otherwise unused
* if (compareAndSetState(0, 1)) {
* setExclusiveOwnerThread(Thread.currentThread());
* return true;
* }
* return false;
* }
*
* // Releases the lock by setting state to zero
* protected boolean tryRelease(int releases) {
* assert releases == 1; // Otherwise unused
* if (getState() == 0) throw new IllegalMonitorStateException();
* setExclusiveOwnerThread(null);
* setState(0);
* return true;
* }
*
* // Provides a Condition
* Condition newCondition() { return new ConditionObject(); }
*
* // Deserializes properly
* private void readObject(ObjectInputStream s)
* throws IOException, ClassNotFoundException {
* s.defaultReadObject();
* setState(0); // reset to unlocked state
* }
* }
*
* // The sync object does all the hard work. We just forward to it.
* private final Sync sync = new Sync();
*
* public void lock() { sync.acquire(1); }
* public boolean tryLock() { return sync.tryAcquire(1); }
* public void unlock() { sync.release(1); }
* public Condition newCondition() { return sync.newCondition(); }
* public boolean isLocked() { return sync.isHeldExclusively(); }
* public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); }
* public void lockInterruptibly() throws InterruptedException {
* sync.acquireInterruptibly(1);
* }
* public boolean tryLock(long timeout, TimeUnit unit)
* throws InterruptedException {
* return sync.tryAcquireNanos(1, unit.toNanos(timeout));
* }
* }}
*
* 这是一个类似CountDownLatch的闩锁类,不同之处在于它只需要一个信号就可以触发。
* 因为锁存是非排他性的,所以它使用共享的获取和释放方法。
*
*
* class BooleanLatch {
*
* private static class Sync extends AbstractQueuedSynchronizer {
* boolean isSignalled() { return getState() != 0; }
*
* protected int tryAcquireShared(int ignore) {
* return isSignalled() ? 1 : -1;
* }
*
* protected boolean tryReleaseShared(int ignore) {
* setState(1);
* return true;
* }
* }
*
* private final Sync sync = new Sync();
* public boolean isSignalled() { return sync.isSignalled(); }
* public void signal() { sync.releaseShared(1); }
* public void await() throws InterruptedException {
* sync.acquireSharedInterruptibly(1);
* }
* }}
*/
public abstract class AbstractQueuedSynchronizer
extends AbstractOwnableSynchronizer
implements java.io.Serializable {

private static final long serialVersionUID = 7373984972572414691L;

/**
* 创建一个初始同步状态为0的新AbstractQueuedSynchronizer实例。
*/
protected AbstractQueuedSynchronizer() { }

/**
* 等待队列节点类。
*
* 等待队列是“CLH”(Craig、Landin和Hagersten)锁定队列的一种变体。CLH锁通常用于自旋锁。
* 相反,我们将它们用于阻塞同步器,但使用相同的基本策略,即在其节点的前身中保存有关线程的一些控制信息。
* 每个节点中的“状态”字段跟踪线程是否应该阻塞。当一个节点的前身释放时,它会收到信号。
* 队列的每个节点充当特定通知样式的监视器,持有单个等待线程。状态字段并不控制线程是否被授予锁等。
* 如果线程位于队列的第一个,则可以尝试获取。但做第一并不能保证成功;它只赋予人们争辩的权利。
* 因此,当前释放的竞争者线程可能需要重新等待。
*
* 要排队进入CLH锁,需要自动地将其拼接为新尾。要脱队,只需设置head字段。
* +------+ prev +-----+ +-----+
* head | | <---- | | <---- | | tail
* +------+ +-----+ +-----+
*
*
* 插入到CLH队列只需要对“尾部”进行单个原子操作,因此存在从未排队到排队的简单原子分界点。
* 类似地,脱离队列只涉及更新“头部”。然而,节点需要做更多的工作来确定谁是它们的后继者,
* 部分原因是为了处理由于超时和中断而可能取消的情况。
*
* “prev”链接(在原来的CLH锁中没有使用)主要用于处理取消。
* 如果一个节点被取消,它的后继节点(通常)被重新链接到一个未取消的前继节点。
* 有关自旋锁的类似力学解释,请参阅Scott和Scherer在http://www.cs.rochester.edu/u/scott/synchronization/上发表的论文
*
* 我们还使用“next”链接来执行阻塞机制。
* 每个节点的线程id都保存在自己的节点中,因此前导节点通过遍历下一个链接来确定它是哪个线程,从而通知要唤醒的下一个节点。
* 后继者的确定必须避免与新排队的节点竞争,以设置其前继者的“next”字段。
* 当节点的后继节点为空时,可以通过从自动更新的“尾部”向后检查来解决这个问题。
* (或者换句话说,下一个链接是一种优化,因此我们通常不需要向后扫描。)
*
* 消去为基本算法引入了一定的保守性。
* 由于我们必须轮询其他节点的取消,因此我们可能无法注意到被取消的节点是在我们前面还是后面。
* 解决这个问题的办法是,在继任者被取消时,总是取消他们的停车位,让他们在一个新的前任上稳定下来,
* 除非我们能找到一个未被取消的前任来承担这项责任。
*
* CLH队列需要一个虚拟头节点才能启动。但我们不会在构建时创建它们,因为如果没有争用,那将是浪费精力。
* 相反,将构造节点,并在第一次争用时设置头和尾指针。
*
* 等待条件的线程使用相同的节点,但使用额外的链接。
* 条件只需要在简单(非并发)链接队列中链接节点,因为它们只有在独占状态下才会被访问。
* 等待时,将节点插入条件队列。收到信号后,节点被转移到主队列。状态字段的特殊值用于标记节点所在的队列。
*/
static final class Node {
/** 标记,指示节点在共享模式下等待 */
static final Node SHARED = new Node();
/** 标记,指示节点在独占模式下等待 */
static final Node EXCLUSIVE = null;

/** waitStatus值表示线程已被取消 */
static final int CANCELLED = 1;
/** waitStatus值,指示后继线程需要取消停放 */
static final int SIGNAL = -1;
/** waitStatus值表示线程正在等待某个条件 */
static final int CONDITION = -2;
/**
* waitStatus值,指示下一个获得的应该无条件传播
*/
static final int PROPAGATE = -3;

/**
* 状态字段,只接受值:
* SIGNAL: 该节点的后继节点被(或将很快)阻塞(通过park),因此当前节点必须在其释放或取消后继节点时解除其park。
* 为了避免竞争,获取方法必须首先表明它们需要一个信号,然后重试原子获取,然后在失败时阻塞。
* CANCELLED: 由于超时或中断,该节点被取消。节点永远不会离开此状态。特别是,具有取消节点的线程再也不会阻塞。
* CONDITION: 该节点当前位于条件队列中。在传输之前,它不会被用作同步队列节点,此时状态将设置为0。
* (这里使用这个值与该字段的其他用法无关,但可以简化机制。)
* PROPAGATE: release共享应该传播到其他节点。
* 这是在doreleaseshare中设置的(仅针对头节点),以确保传播继续进行,即使其他操作已经介入。
* 0: 以上皆非
*
* 这些值以数字形式排列以简化使用。非负值意味着节点不需要发出信号。
* 因此,大多数代码不需要检查特定的值,只需要检查符号。
*
* 对于普通同步节点,该字段初始化为0,对于条件节点,该字段初始化为CONDITION。
* 可以使用CAS(或者在可能的情况下,使用无条件的volatile写)修改它。
*/
volatile int waitStatus;

/**
* 链接到当前节点/线程检查waitStatus所依赖的前身节点。
* 在排队期间分配,仅在离开队列时为空(为了GC)。
* 此外,在取消前一个节点时,我们会在找到一个未取消的节点时短路,因为头部节点从未被取消,因此始终存在:
* 节点仅作为获取成功的结果才成为头部节点。被取消的线程永远不会成功获取,并且线程只会取消自己,而不会取消任何其他节点。
*/
volatile Node prev;

/**
* 链接到当前节点/线程在释放时解除锁定的后继节点。
* 在排队期间分配,在绕过取消的前辈时进行调整,在退出队列时为空(为了GC)。
* enq操作直到附加之后才会分配前一个节点的next字段,因此看到一个空的next字段并不一定意味着节点位于队列的末尾。
* 但是,如果next字段显示为空,我们可以从尾部扫描prev进行双重检查。
* 取消节点的下一个字段被设置为指向节点本身,而不是null,以使isOnSyncQueue更容易。
*/
volatile Node next;

/**
* 使该节点排队的线程。构造时初始化,使用后无效。
*/
volatile Thread thread;

/**
* 链接到下一个等待条件的节点,或特殊值SHARED。
* 因为条件队列只有在以独占模式保持时才会被访问,所以我们只需要一个简单的链接队列来保持等待条件的节点。
* 然后将它们转移到队列中重新获取。由于条件只能是排他性的,所以我们通过使用特殊值来表示共享模式来保存字段。
*/
Node nextWaiter;

/**
* 如果节点处于共享模式等待,则返回true。
*/
final boolean isShared() {
return nextWaiter == SHARED;
}

/**
* 返回前一个节点,如果为空则抛出NullPointerException。
* 当前导不能为空时使用。空检查可以被省略,但存在是为了帮助VM。
*/
final Node predecessor() throws NullPointerException {
Node p = prev;
if (p == null)
throw new NullPointerException();
else
return p;
}

Node() { // 用于建立初始头或共享标记
}

Node(Thread thread, Node mode) { // 由addWaiter使用
this.nextWaiter = mode;
this.thread = thread;
}

Node(Thread thread, int waitStatus) { // 按条件使用
this.waitStatus = waitStatus;
this.thread = thread;
}
}

/**
* 等待队列的头部,惰性初始化。除了初始化之外,它只能通过sehead方法进行修改。
* 注意:如果head存在,它的waitStatus保证不会被取消。
*/
private transient volatile Node head;

/**
* 等待队列的尾部,惰性初始化。仅通过方法enq修改以添加新的等待节点。
*/
private transient volatile Node tail;

/**
* 同步状态。
*/
private volatile int state;

/**
* 返回同步状态的当前值。该操作具有易失读的内存语义。
*/
protected final int getState() {
return state;
}

/**
* 设置同步状态的值。该操作具有易失性写的内存语义。
*/
protected final void setState(int newState) {
state = newState;
}

/**
* 如果当前状态值等于期望值,则自动将同步状态设置为给定的更新值。该操作具有易失性读写的内存语义。
*/
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}

// Queuing utilities

/**
* 旋转比计时停车快的纳秒数。粗略的估计足以在非常短的超时时间内提高响应性。
*/
static final long spinForTimeoutThreshold = 1000L;

/**
* 将节点插入队列,必要时进行初始化。见上图。
*/
private Node enq(final Node node) {
for (;;) {
Node t = tail;
if (t == null) { // Must initialize
if (compareAndSetHead(new Node()))
tail = head;
} else {
node.prev = t;
if (compareAndSetTail(t, node)) {
t.next = node;
return t;
}
}
}
}

/**
* 为当前线程和给定模式创建和排队节点。
*/
private Node addWaiter(Node mode) {
Node node = new Node(Thread.currentThread(), mode);
// Try the fast path of enq; backup to full enq on failure
Node pred = tail;
if (pred != null) {
node.prev = pred;
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
enq(node);
return node;
}

/**
* 将队列的头部设置为node,从而脱离队列。只能由acquire方法调用。
* 为了GC和抑制不必要的信号和遍历,还将未使用的字段清空。
*/
private void setHead(Node node) {
head = node;
node.thread = null;
node.prev = null;
}

/**
* 唤醒节点的后继者(如果存在)。
*/
private void unparkSuccessor(Node node) {
/*
* 如果状态为负(即,可能需要信号),尝试在预期信号时清除。如果此操作失败或状态被等待线程更改,则没有问题。
*/
int ws = node.waitStatus;
if (ws < 0)
compareAndSetWaitStatus(node, ws, 0);

/*
* 要解除停放的线程保存在后继节点中,后继节点通常是下一个节点。
* 但如果被取消或明显为null,则从尾部向后遍历以找到实际未被取消的后继者。
*/
Node s = node.next;
if (s == null || s.waitStatus > 0) {
s = null;
for (Node t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0)
s = t;
}
if (s != null)
LockSupport.unpark(s.thread);
}

/**
* 共享模式的释放动作——信号后继并确保传播。(注:对于独占模式,如果需要信号,释放就相当于调用head的unparkSuccessor。)
*/
private void doReleaseShared() {
/*
* 确保一个发布传播,即使有其他正在进行的获取/发布。
* 这以通常的方式进行,如果需要信号,则尝试unparkSuccessor of head。
* 但如果没有,则将status设置为PROPAGATE,以确保在发布时继续传播。
* 此外,如果在执行此操作时添加了新节点,则必须进行循环。
* 此外,与unparkSuccessor的其他用途不同,我们需要知道CAS重置状态是否失败,如果失败,则需要重新检查。
*/
for (;;) {
Node h = head;
if (h != null && h != tail) {
int ws = h.waitStatus;
if (ws == Node.SIGNAL) {
if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
continue; // 循环以重新检查案例
unparkSuccessor(h);
}
else if (ws == 0 &&
!compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
continue; // CAS失败循环
}
if (h == head) // 如果头部改变,则循环
break;
}
}

/**
* 设置队列头,并检查后继队列是否在共享模式下等待,如果是,则传播propagate > 0或propagate状态设置。
*/
private void setHeadAndPropagate(Node node, int propagate) {
Node h = head; // 记录旧头以备下面核对
setHead(node);
/*
* 尝试向下一个排队节点发出信号:
* 传播由调用者指示,
* 或者被之前的操作记录(在sehead之前或之后作为h.waitStatus)
* (注意:这使用waitStatus的签名检查,因为PROPAGATE状态可能会转换到SIGNAL)。
* 并且
* 下一个节点正在以共享模式等待,
* 或者我们不知道,因为它看起来是空的。
*
* 这两种检查的保守性可能会导致不必要的唤醒,但只有在有多个竞速获取/释放时,所以大多数人现在或很快就需要信号。
*/
if (propagate > 0 || h == null || h.waitStatus < 0 ||
(h = head) == null || h.waitStatus < 0) {
Node s = node.next;
if (s == null || s.isShared())
doReleaseShared();
}
}

// 用于各种版本的工具

/**
* 取消正在进行的获取尝试。
*/
private void cancelAcquire(Node node) {
// 如果节点不存在,则忽略
if (node == null)
return;

node.thread = null;

// 跳过取消的前任
Node pred = node.prev;
while (pred.waitStatus > 0)
node.prev = pred = pred.prev;

// predNext是要取消拼接的明显节点。如果没有,下面的情况将失败,
// 在这种情况下,我们输掉了与另一个取消或信号的比赛,所以不需要进一步的操作。
Node predNext = pred.next;

// 这里可以使用无条件写入而不是CAS。在这个原子步骤之后,其他节点可以跳过我们。
// 之前,我们不受其他线程的干扰。
node.waitStatus = Node.CANCELLED;

// 如果我们是尾巴,那就把自己挪开。
if (node == tail && compareAndSetTail(node, pred)) {
compareAndSetNext(pred, predNext, null);
} else {
// 如果后继者需要信号,试着设置pred的下一个链接,这样它就会得到信号。否则唤醒它来传播。
int ws;
if (pred != head &&
((ws = pred.waitStatus) == Node.SIGNAL ||
(ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&
pred.thread != null) {
Node next = node.next;
if (next != null && next.waitStatus <= 0)
compareAndSetNext(pred, predNext, next);
} else {
unparkSuccessor(node);
}

node.next = node; // 帮助GC
}
}

/**
* 检查并更新获取失败节点的状态。如果线程阻塞,返回true。
* 这是所有采集环路中的主要信号控制。要求pred == node.prev。
*/
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
int ws = pred.waitStatus;
if (ws == Node.SIGNAL)
/*
* 这个节点已经设置了一个状态,请求释放给它发出信号,这样它就可以安全地停放了。
*/
return true;
if (ws > 0) {
/*
* 前任被取消。跳过前一项并指示重试。
*/
do {
node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);
pred.next = node;
} else {
/*
* waitStatus必须为0或PROPAGATE。说我们需要信号,但先别park。
* 调用方需要重试以确保在停车前无法获取。
*/
compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
}
return false;
}

/**
* 方便的方法来中断当前线程。
*/
static void selfInterrupt() {
Thread.currentThread().interrupt();
}

/**
* 方便方法park,然后检查是否中断。
*/
private final boolean parkAndCheckInterrupt() {
LockSupport.park(this);
return Thread.interrupted();
}

/*
* 各种各样的获取方式,包括独占/共享和控制模式。每一种都大同小异,但又有令人恼火的不同。
* 由于异常机制(包括确保在tryAcquire抛出异常时取消)和其他控制的相互作用,
* 只有一点点的分解是可能的,至少不会对性能造成太大的损害。
*/

/**
* 为已经在队列中的线程以独占不可中断模式获取。用于条件等待方法和获取方法。
*/
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; // 帮助GC
failed = false;
return interrupted;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}

/**
* 以独占可中断模式获取。
*/
private void doAcquireInterruptibly(int arg)
throws InterruptedException {
final Node node = addWaiter(Node.EXCLUSIVE);
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null; // 帮助GC
failed = false;
return;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}

/**
* 在独占定时模式下获得。
*/
private boolean doAcquireNanos(int arg, long nanosTimeout)
throws InterruptedException {
if (nanosTimeout <= 0L)
return false;
final long deadline = System.nanoTime() + nanosTimeout;
final Node node = addWaiter(Node.EXCLUSIVE);
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null; // 帮助GC
failed = false;
return true;
}
nanosTimeout = deadline - System.nanoTime();
if (nanosTimeout <= 0L)
return false;
if (shouldParkAfterFailedAcquire(p, node) &&
nanosTimeout > spinForTimeoutThreshold)
LockSupport.parkNanos(this, nanosTimeout);
if (Thread.interrupted())
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}

/**
* 以共享不间断模式获取。
*/
private void doAcquireShared(int arg) {
final Node node = addWaiter(Node.SHARED);
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head) {
int r = tryAcquireShared(arg);
if (r >= 0) {
setHeadAndPropagate(node, r);
p.next = null; // 帮助GC
if (interrupted)
selfInterrupt();
failed = false;
return;
}
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}

/**
* 以共享可中断模式获取。
*/
private void doAcquireSharedInterruptibly(int arg)
throws InterruptedException {
final Node node = addWaiter(Node.SHARED);
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();
if (p == head) {
int r = tryAcquireShared(arg);
if (r >= 0) {
setHeadAndPropagate(node, r);
p.next = null; // 帮助GC
failed = false;
return;
}
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}

/**
* 在共享定时模式下获取。
*/
private boolean doAcquireSharedNanos(int arg, long nanosTimeout)
throws InterruptedException {
if (nanosTimeout <= 0L)
return false;
final long deadline = System.nanoTime() + nanosTimeout;
final Node node = addWaiter(Node.SHARED);
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();
if (p == head) {
int r = tryAcquireShared(arg);
if (r >= 0) {
setHeadAndPropagate(node, r);
p.next = null; // 帮助GC
failed = false;
return true;
}
}
nanosTimeout = deadline - System.nanoTime();
if (nanosTimeout <= 0L)
return false;
if (shouldParkAfterFailedAcquire(p, node) &&
nanosTimeout > spinForTimeoutThreshold)
LockSupport.parkNanos(this, nanosTimeout);
if (Thread.interrupted())
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}

// 主要导出方法

/**
* 尝试以独占模式获取。该方法应该查询对象的状态是否允许以独占模式获取它,如果允许则获取它。
*
* 此方法总是由执行acquire的线程调用。如果此方法报告失败,则acquire方法可能会将线程(如果尚未排队)放入队列,
* 直到其他线程发出释放信号为止。这可以用来实现方法Lock.tryLock()。
*
* 默认实现抛出UnsupportedOperationException。
*/
protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}

/**
* 尝试将状态设置为在独占模式下反映释放。
* 此方法总是由执行释放的线程调用。
* 默认实现抛出UnsupportedOperationException。
*/
protected boolean tryRelease(int arg) {
throw new UnsupportedOperationException();
}

/**
* 在共享模式下尝试获取。该方法应该查询对象的状态是否允许以共享模式获取它,如果允许则获取它。
*
* 此方法总是由执行acquire的线程调用。如果此方法报告失败,则acquire方法可能会将线程(如果尚未排队)放入队列,、
* 直到其他线程发出释放信号为止。
*
* 默认实现抛出UnsupportedOperationException。
*/
protected int tryAcquireShared(int arg) {
throw new UnsupportedOperationException();
}

/**
* 尝试将状态设置为反映共享模式下的释放。
* 此方法总是由执行释放的线程调用。
* 默认实现抛出UnsupportedOperationException。
*/
protected boolean tryReleaseShared(int arg) {
throw new UnsupportedOperationException();
}

/**
* 如果对当前(调用)线程独占保持同步,则返回true。此方法在每次调用非等待的AbstractQueuedSynchronizer.ConditionObject方法。(等待方法调用释放。)
* 默认实现抛出UnsupportedOperationException。此方法仅在AbstractQueuedSynchronizer内部调用。
* 如果不使用条件,则不需要定义ConditionObject方法。
*/
protected boolean isHeldExclusively() {
throw new UnsupportedOperationException();
}

/**
* 以独占模式获取,忽略中断。通过调用至少一次tryAcquire实现,成功时返回。
* 否则,线程将被排队,可能会反复阻塞和解除阻塞,调用tryAcquire直到成功。这个方法可以用来实现方法Lock.lock。
*/
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}

/**
* 以独占模式获取,如果中断则中止。首先检查中断状态,然后调用至少一次tryAcquire,成功时返回。
* 否则,线程将被排队,可能会反复阻塞和解除阻塞,调用tryAcquire,直到成功或线程被中断。
* 此方法可用于实现方法Lock.lockInterruptibly。
*/
public final void acquireInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (!tryAcquire(arg))
doAcquireInterruptibly(arg);
}

/**
* 尝试在独占模式下获取,如果中断则中止,如果给定的超时过期则失败。首先检查中断状态,然后调用至少一次tryAcquire,成功时返回。
* 否则,线程将被排队,可能会反复阻塞和解阻塞,调用tryAcquire,直到成功或线程被中断或超时结束。
* 此方法可用于实现方法Lock.tryLock(long, TimeUnit)。
*/
public final boolean tryAcquireNanos(int arg, long nanosTimeout)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
return tryAcquire(arg) ||
doAcquireNanos(arg, nanosTimeout);
}

/**
* 以独占模式释放。通过在tryRelease返回true时解除一个或多个线程的阻塞实现。
* 这个方法可以用来实现方法Lock.unlock。
*/
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}

/**
* 在共享模式下获取,忽略中断。通过首先调用至少一次tryacquirered实现,成功时返回。
* 否则,线程将被排队,可能会反复阻塞和解阻塞,调用tryacquirered直到成功。
*/
public final void acquireShared(int arg) {
if (tryAcquireShared(arg) < 0)
doAcquireShared(arg);
}

/**
* 在共享模式下获取,中断时中止。通过首先检查中断状态实现,然后至少调用一次tryacquirered,成功返回。
* 否则,线程将被排队,可能会反复阻塞和解除阻塞,调用tryacquirered,直到成功或线程被中断。
*/
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)
doAcquireSharedInterruptibly(arg);
}

/**
* 尝试在共享模式下获取,如果中断则中止,如果给定的超时过期则失败。通过首先检查中断状态实现,然后至少调用一次tryacquirered,成功返回。
* 否则,线程将被排队,可能会反复阻塞和解阻塞,调用tryacquirered,直到成功或线程被中断或超时。
*/
public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
return tryAcquireShared(arg) >= 0 ||
doAcquireSharedNanos(arg, nanosTimeout);
}

/**
* 以共享方式释放。通过在tryreleaseshare返回true时解除一个或多个线程的阻塞来实现。
*/
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();
return true;
}
return false;
}

// 队列检查方法

/**
* 查询是否有线程正在等待获取。请注意,由于中断和超时导致的取消可能随时发生,因此真正的返回并不能保证任何其他线程都会获得。
*/
public final boolean hasQueuedThreads() {
return head != tail;
}

/**
* 查询是否有线程争用这个同步器;也就是说,如果一个获取方法曾经阻塞过。
* 在这个实现中,这个操作在常量时间内返回。
*/
public final boolean hasContended() {
return head != null;
}

/**
* 返回队列中第一个(等待时间最长的)线程,如果当前没有线程排队,则返回null。
* 在此实现中,此操作通常在常量时间内返回,但如果其他线程并发地修改队列,则可能在争用时迭代。
*/
public final Thread getFirstQueuedThread() {
// handle only fast path, else relay
return (head == tail) ? null : fullGetFirstQueuedThread();
}

/**
* fastpath失败时调用的getFirstQueuedThread的版本
*/
private Thread fullGetFirstQueuedThread() {
/*
* 第一个节点通常是head.next。尝试获取它的thread字段,确保读取的一致性:
* 如果thread字段被清空,或者s.prev不再是head,那么其他线程会在我们的一些
* 读取之间并发地执行sehead。在使用遍历之前,我们尝试了两次。
*/
Node h, s;
Thread st;
if (((h = head) != null && (s = h.next) != null &&
s.prev == head && (st = s.thread) != null) ||
((h = head) != null && (s = h.next) != null &&
s.prev == head && (st = s.thread) != null))
return st;

/*
* Head的下一个字段可能尚未设置,或者可能在sehead之后未设置。
* 所以我们必须检查tail是否真的是第一个节点。如果没有,我们继续,从尾部安全地穿越到头部以找到第一个,保证终止。
*/

Node t = tail;
Thread firstThread = null;
while (t != null && t != head) {
Thread tt = t.thread;
if (tt != null)
firstThread = tt;
t = t.prev;
}
return firstThread;
}

/**
* 如果给定线程当前正在排队,则返回true。
* 这个实现遍历队列以确定给定线程是否存在。
*/
public final boolean isQueued(Thread thread) {
if (thread == null)
throw new NullPointerException();
for (Node p = tail; p != null; p = p.prev)
if (p.thread == thread)
return true;
return false;
}

/**
* 如果第一个排队的线程(如果存在)以排他模式等待,则返回true。
* 如果此方法返回true,并且当前线程正在尝试以共享模式获取(即,从tryacquirered调用此方法),
* 则可以保证当前线程不是第一个排队的线程。仅在ReentrantReadWriteLock中用作启发式。
*/
final boolean apparentlyFirstQueuedIsExclusive() {
Node h, s;
return (h = head) != null &&
(s = h.next) != null &&
!s.isShared() &&
s.thread != null;
}

/**
* 查询是否有线程等待获取的时间比当前线程长。
* 此方法的调用相当于(但可能比):
*
* getFirstQueuedThread() != Thread.currentThread() && hasQueuedThreads()
*
* 请注意,由于中断和超时导致的取消可能随时发生,因此真正的返回并不能保证其他线程会在当前线程之前获得。
* 同样,在此方法返回false后,由于队列为空,另一个线程也可能赢得进入队列的竞争。
*
* 这种方法被设计为由公平同步器使用,以避免碰撞。这样的同步器的tryAcquire方法应该返回false,如果这个方法返回true,
* 那么它的tryacquirered方法应该返回一个负值(除非这是一个可重入的获取)。
* 例如,公平、可重入、独占模式同步器的tryAcquire方法可能如下所示:
*
* protected boolean tryAcquire(int arg) {
* if (isHeldExclusively()) {
* // 可重入获取;增量保持计数
* return true;
* } else if (hasQueuedPredecessors()) {
* return false;
* } else {
* // 试着正常获取
* }
* }
*/
public final boolean hasQueuedPredecessors() {
// 它的正确性取决于head在tail之前初始化,也取决于head。如果当前线程是队列中的第一个,则Next是准确的。
Node t = tail; // 以相反的初始化顺序读取字段
Node h = head;
Node s;
return h != t &&
((s = h.next) == null || s.thread != Thread.currentThread());
}


// 仪器仪表和监测方法

/**
* 返回等待获取的线程数的估计值。该值只是一个估计值,因为当此方法遍历内部数据结构时,线程的数量可能会动态变化。
* 这种方法设计用于监测系统状态,而不是用于同步控制。
*/
public final int getQueueLength() {
int n = 0;
for (Node p = tail; p != null; p = p.prev) {
if (p.thread != null)
++n;
}
return n;
}

/**
* 返回一个包含可能正在等待获取的线程的集合。由于在构造此结果时,实际的线程集可能会动态变化,
* 因此返回的集合只是尽力而为的估计值。返回集合的元素没有特定的顺序。
* 该方法旨在促进子类的构建,从而提供更广泛的监视功能。
*/
public final Collection<Thread> getQueuedThreads() {
ArrayList<Thread> list = new ArrayList<Thread>();
for (Node p = tail; p != null; p = p.prev) {
Thread t = p.thread;
if (t != null)
list.add(t);
}
return list;
}

/**
* 返回一个集合,其中包含可能正在等待以独占模式获取的线程。
* 这与getQueuedThreads具有相同的属性,除了它只返回那些由于独占获取而等待的线程。
*/
public final Collection<Thread> getExclusiveQueuedThreads() {
ArrayList<Thread> list = new ArrayList<Thread>();
for (Node p = tail; p != null; p = p.prev) {
if (!p.isShared()) {
Thread t = p.thread;
if (t != null)
list.add(t);
}
}
return list;
}

/**
* 返回一个集合,其中包含可能正在等待以共享模式获取的线程。
* 这与getQueuedThreads具有相同的属性,除了它只返回那些由于共享获取而等待的线程。
*/
public final Collection<Thread> getSharedQueuedThreads() {
ArrayList<Thread> list = new ArrayList<Thread>();
for (Node p = tail; p != null; p = p.prev) {
if (p.isShared()) {
Thread t = p.thread;
if (t != null)
list.add(t);
}
}
return list;
}

/**
* 返回标识此同步器及其状态的字符串。括号中的状态包括字符串“state =”,
* 后面跟着getState的当前值,以及取决于队列是否为空的“非空”或“空”。
*/
public String toString() {
int s = getState();
String q = hasQueuedThreads() ? "non" : "";
return super.toString() +
"[State = " + s + ", " + q + "empty queue]";
}


// 条件的内部支持方法

/**
* 如果节点(总是初始放置在条件队列中的节点)现在正在等待同步队列上重新获取,则返回true。
*/
final boolean isOnSyncQueue(Node node) {
if (node.waitStatus == Node.CONDITION || node.prev == null)
return false;
if (node.next != null) // 如果有继任者,它必须在队列中
return true;
/*
* node.prev可以是非空的,但还不能在队列上,因为将它放在队列上的CAS可能会失败。
* 所以我们必须从尾巴开始遍历,以确保它确实做到了。在调用此方法时,它将始终位于尾部附近,
* 除非CAS失败(这是不太可能的),否则它将在那里,因此我们几乎不会遍历太多。
*/
return findNodeFromTail(node);
}

/**
* 如果从尾部向后搜索节点在同步队列上,则返回true。只在isOnSyncQueue需要时调用。
*/
private boolean findNodeFromTail(Node node) {
Node t = tail;
for (;;) {
if (t == node)
return true;
if (t == null)
return false;
t = t.prev;
}
}

/**
* 将节点从条件队列传输到同步队列。如果成功返回true。
*/
final boolean transferForSignal(Node node) {
/*
* 如果不能更改waitStatus,则节点已被取消。
*/
if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
return false;

/*
* 拼接到队列上,并尝试设置前一个线程的waitStatus,以表明线程(可能)正在等待。
* 如果取消或尝试设置waitStatus失败,则唤醒以重新同步(在这种情况下,waitStatus可能是暂时且无害的错误)。
*/
Node p = enq(node);
int ws = p.waitStatus;
if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
LockSupport.unpark(node.thread);
return true;
}

/**
* 如果需要,在取消等待后将节点传输到同步队列。如果线程在收到信号之前被取消,则返回true。
*/
final boolean transferAfterCancelledWait(Node node) {
if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
enq(node);
return true;
}
/*
* 如果我们丢失了 signal(),,那么我们不能继续,直到它完成它的enq()。在不完全转移期间取消既罕见又短暂,所以只需旋转。
*/
while (!isOnSyncQueue(node))
Thread.yield();
return false;
}

/**
* 使用当前状态值调用释放;返回保存状态。取消节点并在失败时抛出异常。
*/
final int fullyRelease(Node node) {
boolean failed = true;
try {
int savedState = getState();
if (release(savedState)) {
failed = false;
return savedState;
} else {
throw new IllegalMonitorStateException();
}
} finally {
if (failed)
node.waitStatus = Node.CANCELLED;
}
}

// 条件测量方法

/**
* 查询给定的ConditionObject是否使用此同步器作为其锁。
*/
public final boolean owns(ConditionObject condition) {
return condition.isOwnedBy(this);
}

/**
* 查询是否有线程正在等待与此同步器关联的给定条件。请注意,由于超时和中断可能随时发生,
* 因此真正的返回并不能保证将来的信号将唤醒任何线程。这种方法主要是为监视系统状态而设计的。
*/
public final boolean hasWaiters(ConditionObject condition) {
if (!owns(condition))
throw new IllegalArgumentException("Not owner");
return condition.hasWaiters();
}

/**
* 返回与此同步器关联的等待给定条件的线程数的估计值。请注意,由于超时和中断可能随时发生,
* 因此估计仅作为实际等待者数量的上界。这种方法设计用于监视系统状态,而不是用于同步控制。
*/
public final int getWaitQueueLength(ConditionObject condition) {
if (!owns(condition))
throw new IllegalArgumentException("Not owner");
return condition.getWaitQueueLength();
}

/**
* 返回一个集合,其中包含可能正在等待与此同步器关联的给定条件的线程。
* 由于在构造此结果时,实际的线程集可能会动态变化,因此返回的集合只是尽力而为的估计值。返回集合的元素没有特定的顺序。
*/
public final Collection<Thread> getWaitingThreads(ConditionObject condition) {
if (!owns(condition))
throw new IllegalArgumentException("Not owner");
return condition.getWaitingThreads();
}

/**
* 作为Lock实现基础的AbstractQueuedSynchronizer的条件实现。
* 该类的方法文档从锁定和条件用户的角度描述了机制,而不是行为规范。
* 这个类的导出版本通常需要附带描述依赖于相关AbstractQueuedSynchronizer的条件语义的文档。
* 这个类是可序列化的,但所有字段都是临时的,因此反序列化的条件没有等待者。
*/
public class ConditionObject implements Condition, java.io.Serializable {
private static final long serialVersionUID = 1173984872572414699L;
/** 条件队列的第一个节点。 */
private transient Node firstWaiter;
/** 条件队列的最后一个节点。 */
private transient Node lastWaiter;

/**
* 创建一个新的ConditionObject实例
*/
public ConditionObject() { }

// 内部方法

/**
* 在等待队列中添加一个新的等待者。
*/
private Node addConditionWaiter() {
Node t = lastWaiter;
// 如果最后一个等待者被取消,请清理出去。
if (t != null && t.waitStatus != Node.CONDITION) {
unlinkCancelledWaiters();
t = lastWaiter;
}
Node node = new Node(Thread.currentThread(), Node.CONDITION);
if (t == null)
firstWaiter = node;
else
t.nextWaiter = node;
lastWaiter = node;
return node;
}

/**
* 移除并转移节点,直到命中未取消的节点或为空。从信号中分离出来部分是为了鼓励编译器内联没有等待者的情况。
*/
private void doSignal(Node first) {
do {
if ( (firstWaiter = first.nextWaiter) == null)
lastWaiter = null;
first.nextWaiter = null;
} while (!transferForSignal(first) &&
(first = firstWaiter) != null);
}

/**
* 移除并传输所有节点。
*/
private void doSignalAll(Node first) {
lastWaiter = firstWaiter = null;
do {
Node next = first.nextWaiter;
first.nextWaiter = null;
transferForSignal(first);
first = next;
} while (first != null);
}

/**
* 从条件队列中解除已取消的服务员节点的链接。只在持有锁时调用。
* 当条件等待期间发生取消时,以及当lastWaiter被取消时插入新侍者时,调用该函数。
* 在没有信号的情况下,需要使用此方法来避免垃圾保留。因此,尽管它可能需要一次完整的遍历,但只有在没有信号的情况下发生超时或取消时,它才会发挥作用。
* 它遍历所有节点,而不是在一个特定的目标上停止,以解除指向垃圾节点的所有指针的链接,而不需要在取消风暴期间进行多次重新遍历。
*/
private void unlinkCancelledWaiters() {
Node t = firstWaiter;
Node trail = null;
while (t != null) {
Node next = t.nextWaiter;
if (t.waitStatus != Node.CONDITION) {
t.nextWaiter = null;
if (trail == null)
firstWaiter = next;
else
trail.nextWaiter = next;
if (next == null)
lastWaiter = trail;
}
else
trail = t;
t = next;
}
}

// 公共方法

/**
* 将等待时间最长的线程(如果存在)从此条件的等待队列移动到拥有锁的等待队列。
*/
public final void signal() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
Node first = firstWaiter;
if (first != null)
doSignal(first);
}

/**
* 将此条件的所有线程从等待队列移动到拥有锁的等待队列。
*/
public final void signalAll() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
Node first = firstWaiter;
if (first != null)
doSignalAll(first);
}

/**
* 实现不间断条件等待。
*
* 1. 保存getState返回的锁状态。
* 2. 以保存的状态作为参数调用release,如果失败则抛出IllegalMonitorStateException。
* 3. 等待信号。
* 4. 通过以保存状态作为参数调用acquire的特殊版本来重新获取。
*/
public final void awaitUninterruptibly() {
Node node = addConditionWaiter();
int savedState = fullyRelease(node);
boolean interrupted = false;
while (!isOnSyncQueue(node)) {
LockSupport.park(this);
if (Thread.interrupted())
interrupted = true;
}
if (acquireQueued(node, savedState) || interrupted)
selfInterrupt();
}

/*
* 对于可中断的等待,我们需要跟踪是否抛出InterruptedException,
* 如果在阻塞条件下中断,而不是重新中断当前线程,如果在阻塞等待重新获取时中断。
*/

/** 模式,意思是从等待退出时重新中断 */
private static final int REINTERRUPT = 1;
/** 模式意味着在退出等待时抛出InterruptedException */
private static final int THROW_IE = -1;

/**
* 检查中断,如果在发出信号之前中断返回THROW_IE,如果在发出信号之后返回REINTERRUPT,如果没有中断返回0。
*/
private int checkInterruptWhileWaiting(Node node) {
return Thread.interrupted() ?
(transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :
0;
}

/**
* 抛出InterruptedException,重新中断当前线程,或者什么都不做,具体取决于模式。
*/
private void reportInterruptAfterWait(int interruptMode)
throws InterruptedException {
if (interruptMode == THROW_IE)
throw new InterruptedException();
else if (interruptMode == REINTERRUPT)
selfInterrupt();
}

/**
* 实现可中断条件等待。
*
* 1. 如果当前线程被中断,抛出InterruptedException。
* 2. 保存getState返回的锁状态。
* 3. 以保存的状态作为参数调用release,如果失败则抛出IllegalMonitorStateException。
* 4. 阻塞直到发出信号或中断。
* 5. 通过以保存状态作为参数调用acquire的特殊版本来重新获取。
* 6. 如果在第4步阻塞时中断,则抛出InterruptedException。
*/
public final void await() throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
Node node = addConditionWaiter();
int savedState = fullyRelease(node);
int interruptMode = 0;
while (!isOnSyncQueue(node)) {
LockSupport.park(this);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
}
if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
interruptMode = REINTERRUPT;
if (node.nextWaiter != null) // 取消后清理
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);
}

/**
* 实现定时条件等待。
*
* 1. 如果当前线程被中断,抛出InterruptedException。
* 2. 保存getState返回的锁状态。
* 3. 以保存的状态作为参数调用release,如果失败则抛出IllegalMonitorStateException。
* 4. 阻塞直到发出信号、中断或超时为止。
* 5. 通过以保存状态作为参数调用acquire的特殊版本来重新获取。
* 6. 如果在第4步阻塞时中断,则抛出InterruptedException。
*/
public final long awaitNanos(long nanosTimeout)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
Node node = addConditionWaiter();
int savedState = fullyRelease(node);
final long deadline = System.nanoTime() + nanosTimeout;
int interruptMode = 0;
while (!isOnSyncQueue(node)) {
if (nanosTimeout <= 0L) {
transferAfterCancelledWait(node);
break;
}
if (nanosTimeout >= spinForTimeoutThreshold)
LockSupport.parkNanos(this, nanosTimeout);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
nanosTimeout = deadline - System.nanoTime();
}
if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
interruptMode = REINTERRUPT;
if (node.nextWaiter != null)
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);
return deadline - System.nanoTime();
}

/**
* 实现绝对定时条件等待。
* 1. 如果当前线程被中断,抛出InterruptedException。
* 2. 保存getState返回的锁状态。
* 3. 以保存的状态作为参数调用release,如果失败则抛出IllegalMonitorStateException。
* 4. 阻塞直到发出信号、中断或超时为止。
* 5. 通过以保存状态作为参数调用acquire的特殊版本来重新获取。
* 6. 如果在第4步阻塞时中断,则抛出InterruptedException。
* 7. 如果在第4步阻塞时超时,则返回false,否则返回true。
*/
public final boolean awaitUntil(Date deadline)
throws InterruptedException {
long abstime = deadline.getTime();
if (Thread.interrupted())
throw new InterruptedException();
Node node = addConditionWaiter();
int savedState = fullyRelease(node);
boolean timedout = false;
int interruptMode = 0;
while (!isOnSyncQueue(node)) {
if (System.currentTimeMillis() > abstime) {
timedout = transferAfterCancelledWait(node);
break;
}
LockSupport.parkUntil(this, abstime);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
}
if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
interruptMode = REINTERRUPT;
if (node.nextWaiter != null)
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);
return !timedout;
}

/**
* 实现定时条件等待。
* 1. 如果当前线程被中断,抛出InterruptedException。
* 2. 保存getState返回的锁状态。
* 3. 以保存的状态作为参数调用release,如果失败则抛出IllegalMonitorStateException。
* 4. 阻塞直到发出信号、中断或超时为止。
* 5. 通过以保存状态作为参数调用acquire的特殊版本来重新获取。
* 6. 如果在第4步阻塞时中断,则抛出InterruptedException。
* 7. 如果在第4步阻塞时超时,则返回false,否则返回true。
*/
public final boolean await(long time, TimeUnit unit)
throws InterruptedException {
long nanosTimeout = unit.toNanos(time);
if (Thread.interrupted())
throw new InterruptedException();
Node node = addConditionWaiter();
int savedState = fullyRelease(node);
final long deadline = System.nanoTime() + nanosTimeout;
boolean timedout = false;
int interruptMode = 0;
while (!isOnSyncQueue(node)) {
if (nanosTimeout <= 0L) {
timedout = transferAfterCancelledWait(node);
break;
}
if (nanosTimeout >= spinForTimeoutThreshold)
LockSupport.parkNanos(this, nanosTimeout);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
nanosTimeout = deadline - System.nanoTime();
}
if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
interruptMode = REINTERRUPT;
if (node.nextWaiter != null)
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);
return !timedout;
}

// 对仪表的支持

/**
* 如果此条件是由给定的同步对象创建的,则返回true。
*/
final boolean isOwnedBy(AbstractQueuedSynchronizer sync) {
return sync == AbstractQueuedSynchronizer.this;
}

/**
* 查询是否有线程正在等待此条件。实现hasWaiters (AbstractQueuedSynchronizer.ConditionObject)。
*/
protected final boolean hasWaiters() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
if (w.waitStatus == Node.CONDITION)
return true;
}
return false;
}

/**
* 返回等待此条件的线程数的估计值。实现getWaitQueueLength (AbstractQueuedSynchronizer.ConditionObject)。
*/
protected final int getWaitQueueLength() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
int n = 0;
for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
if (w.waitStatus == Node.CONDITION)
++n;
}
return n;
}

/**
* 返回一个集合,其中包含可能正在等待此条件的线程。实现getWaitingThreads (AbstractQueuedSynchronizer.ConditionObject)。
*/
protected final Collection<Thread> getWaitingThreads() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
ArrayList<Thread> list = new ArrayList<Thread>();
for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
if (w.waitStatus == Node.CONDITION) {
Thread t = w.thread;
if (t != null)
list.add(t);
}
}
return list;
}
}

/**
* 安装以支持compareAndSet。我们需要在这里本地实现它:为了允许将来的增强,我们不能显式地继承AtomicInteger,
* 否则这将是有效和有用的。因此,作为最小的缺点,我们使用热点固有API来本地实现。同时,我们对其他CASable字段
* 也做同样的事情(否则可以使用原子字段更新器完成)。
*/
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long stateOffset;
private static final long headOffset;
private static final long tailOffset;
private static final long waitStatusOffset;
private static final long nextOffset;

static {
try {
stateOffset = unsafe.objectFieldOffset
(AbstractQueuedSynchronizer.class.getDeclaredField("state"));
headOffset = unsafe.objectFieldOffset
(AbstractQueuedSynchronizer.class.getDeclaredField("head"));
tailOffset = unsafe.objectFieldOffset
(AbstractQueuedSynchronizer.class.getDeclaredField("tail"));
waitStatusOffset = unsafe.objectFieldOffset
(Node.class.getDeclaredField("waitStatus"));
nextOffset = unsafe.objectFieldOffset
(Node.class.getDeclaredField("next"));

} catch (Exception ex) { throw new Error(ex); }
}

/**
* CAS head字段。仅供enq使用。
*/
private final boolean compareAndSetHead(Node update) {
return unsafe.compareAndSwapObject(this, headOffset, null, update);
}

/**
* CAS tail字段。仅供enq使用。
*/
private final boolean compareAndSetTail(Node expect, Node update) {
return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
}

/**
* 节点的CAS waitStatus字段。
*/
private static final boolean compareAndSetWaitStatus(Node node,
int expect,
int update) {
return unsafe.compareAndSwapInt(node, waitStatusOffset,
expect, update);
}

/**
* CAS节点下一个字段。
*/
private static final boolean compareAndSetNext(Node node,
Node expect,
Node update) {
return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
}
}