AbstractQueuedSynchronizer 的内部类 Node
static final class Node {
/**
* Marker to indicate a node is waiting in shared mode
* 用来标记该线程是获取共享资源时被阻塞挂起后放入 AQS 队列的
*/
static final Node SHARED = new Node();
/**
* Marker to indicate a node is waiting in exclusive mode
* 用来标记该线程是获取独占资源时被挂起后放入 AQS 队列的
*/
static final Node EXCLUSIVE = null;
/**
* waitStatus value to indicate thread has cancelled
* waitStatus值:线程被取消了
*/
static final int CANCELLED = 1;
/**
* waitStatus value to indicate successor's thread needs unparking
* waitStatus值:线程需要被唤醒
*/
static final int SIGNAL = -1;
/**
* waitStatus value to indicate thread is waiting on condition
* waitStatus值:线程在条件队列里面等待
*/
static final int CONDITION = -2;
/**
* waitStatus value to indicate the next acquireShared should unconditionally propagate
* waitStatus值:释放共享资源时需要通知其他节点
*/
static final int PROPAGATE = -3;
/**
* 状态字段,仅采用以下值:
*
* SIGNAL:
* 此节点的后续节点已(或即将)被阻塞(通过park),因此当前节点在释放或取消时必须唤醒其后续节点(通过unpark)
* 为了避免竞争,获取方法必须首先指示它们需要信号,然后重试原子获取,然后在失败后阻塞
*
* CANCELLED:
* 该节点因超时或中断被取消。节点永远不会离开这个状态。特别是,节点被取消的线程将不再阻塞。
*
* CONDITION:
* 此节点当前位于条件队列中。在传输之前,它不会被用作同步队列节点,此时状态将被设置为0。
* (此处使用此值与字段的其他用途无关,但简化了机制。)
*
* PROPAGATE:
* releaseShared应传播到其他节点。这是在doReleaseShared中设置的(仅适用于头节点),
* 以确保传播继续,即使其他操作已经介入。
*
* 0: 以上都不是
*
*
* 数值以数字方式排列,以简化使用。非负值表示节点不需要发出信号。因此,大多数代码不需要检查特定值,只需要检查符号。
*
* 对于正常同步节点,该字段初始化为0,对于条件节点初始化为CONDITION。
* 使用CAS(或者在可能的情况下,使用无条件的volatile写入)对它进行修改。
*
*/
volatile int waitStatus;
/**
* 指向当前节点线程的前置节点的链接。
*/
volatile Node prev;
/**
* 指向当前节点线程的后续节点的链接。
*/
volatile Node next;
/**
* 将此节点排入队列的线程。在构造时初始化,使用后为null。
*/
volatile Thread thread;
/**
* 链接到下一个等待条件的节点,或特殊值SHARED。因为只有在独占模式下保持时才能访问条件队列,
* 所以我们只需要一个简单的链接队列来保持节点等待条件。然后将它们转移到队列以重新获取。
* 因为条件只能是互斥的,所以我们通过使用特殊值来表示共享模式来保存字段。
*/
Node nextWaiter;
/**
* 如果节点在共享模式下等待,则返回true。
*/
final boolean isShared() {
return nextWaiter == SHARED;
}
/**
* 返回上一个节点,如果为null,则抛出NullPointerException。
* 当前置项不能为空时使用。空检查可能被取消,但存在以帮助VM。
*/
final Node predecessor() throws NullPointerException {
Node p = prev;
if (p == null)
throw new NullPointerException();
else
return p;
}
Node() { // 用于建立初始标头或SHARED标记
}
Node(Thread thread, Node mode) { // 由 addWaiter 使用
this.nextWaiter = mode;
this.thread = thread;
}
Node(Thread thread, int waitStatus) { // 由 Condition 使用
this.waitStatus = waitStatus;
this.thread = thread;
}
}