前言
- 提供一个框架,用于实现依赖于先进先出(FIFO)等待队列的阻塞锁和相关的同步器(信号灯,事件等)。
- 此类旨在为大多数依赖单个原子{@code int}值表示状态的同步器提供有用的基础。
- 子类必须定义更改此状态的受保护方法,并定义该状态对于获取或释放此对象而言意味着什么。
- 鉴于这些,此类中的其他方法将执行所有排队和阻塞机制。
- 子类可以维护其他状态字段,但是仅跟踪关于同步的使用方法{@link #getState},
- {@link #setState}和{@link #compareAndSetState}操作的原子更新的{@code int}值。
- 子类应定义为用于实现其所在类的同步属性的非公共内部帮助器类。
- 类{@code AbstractQueuedSynchronizer}没有实现任何同步接口。
- 相反,它定义了{@link #acquireInterruptible}之类的方法,可以通过具体的锁和相关的同步器适当地调用这些方法以实现其公共方法。
- 此类支持默认排他模式和共享模式之一或两者。
- 当以独占方式进行获取时,其他线程尝试进行的获取将无法成功。
- 由多个线程获取的共享模式可能(但不一定)成功。
- 该类不“理解”这些差异,只是从机械意义上说,当共享模式获取成功时,下一个等待线程(如果存在)还必须确定它是否也可以获取。
- 在不同模式下等待的线程共享相同的FIFO队列。
- 通常,实现子类仅支持这些模式之一,但例如可以在{@link ReadWriteLock}中发挥作用。
- 仅支持互斥模式或仅共享模式的子类无需定义支持未使用模式的方法。
- 此类定义了一个嵌套的{@link ConditionObject}类,可以由支持独占模式的子类用作{@link Condition}实现,
- 为此方法{@link #isHeldExclusively}报告是否针对当前线程专有地保持同步,
- 使用当前{@link #getState}值调用的方法{@link #release}会完全释放该对象,
- 并且给定已保存的状态值,{@link #acquire}最终会将其恢复为先前的获取状态。
- 否则,没有{@code AbstractQueuedSynchronizer}方法会创建这样的条件,因此,如果不能满足此约束,请不要使用它。
- {@link ConditionObject}的行为当然取决于其同步器实现的语义。
- 此类提供了内部队列的检查,检测和监视方法,以及条件对象的类似方法。
- 可以根据需要使用{@code AbstractQueuedSynchronizer}将它们导出到类中以实现其同步机制。
- 此类的序列化仅存储基础原子整数维护状态,因此反序列化的对象具有空线程队列。
- 需要可序列化的典型子类将定义一个{@code readObject}方法,该方法可在反序列化时将其恢复为已知的初始状态。
- 要将此类用作同步器的基础,请使用{@link #getState},
- {@link #setState}和/或{@link #compareAndSetState检查和/或修改同步状态,重新定义以下方法(如适用) }:
-
-
- {@link #tryAcquire}
-
- {@link #tryRelease}
-
- {@link #tryAcquireShared}
-
- {@link #tryReleaseShared}
-
- {@link #isHeldExclusively}
-
- 默认情况下,这些方法中的每一个都会引发{@link UnsupportedOperationException}。
- 这些方法的实现必须在内部是线程安全的,并且通常应简短且不阻塞。定义这些方法是使用此类的唯一受支持的方法。
- 所有其他方法都声明为{@code final},因为它们不能独立变化。
- 您可能还会发现从{@link AbstractOwnableSynchronizer}继承的方法对于跟踪拥有独占同步器的线程很有用。
- 鼓励您使用它们-这将启用监视和诊断工具,以帮助用户确定哪些线程持有锁。
- 因为在入队之前调用了获取中的检查,所以新获取的线程可能会先于被阻塞和排队的其他线程进行插入。
- 但是,如果需要,您可以定义{@code tryAcquire}和/或{@code tryAcquireShared}来通过内部调用一种或多种检查方法来禁用插入,从而提供公平的FIFO获取顺序。
- 特别是,如果{@link #hasQueuedPredecessors}(一种专门为公平同步器设计的方法)返回{@code true},
- 则大多数公平同步器都可以定义{@code tryAcquire}返回{@code false}。其他变化是可能的。
- 对于默认插入(也称为贪婪,放弃和避免车队)策略,吞吐量和可伸缩性通常最高。
- 尽管不能保证这是公平的,也可以避免饥饿,但允许在较早排队的线程之前重新竞争较早排队的线程,并且每个重新争用都可以毫无偏向地成功抵御传入线程。
- 同样,尽管获取通常不会“旋转”,但是在阻塞之前,它们可能会执行{@code tryAcquire}的多次调用,并插入其他计算。
- 如果仅短暂地保持排他同步,则这将带来旋转的大部分好处,而如果不进行排他同步,则不会带来很多负担。如果需要的话,
- 可以通过在调用之前使用“快速路径”检查来获取方法来增强此功能,
- 可能会预先检查{@link #hasContended}和/或{@link #hasQueuedThreads}以仅在同步器可能不这样做的情况下这样做争辩。
- 此类为同步提供了有效且可扩展的基础,部分原因是通过将其使用范围专门用于可以依靠{@code int}状态,获取和释放参数以及内部FIFO等待队列的同步器。
- 如果这还不够,您可以使用{@link java.util.concurrent.atomic atomic}类,
- 您自己的自定义{@link java.util.Queue}类和{@link LockSupport}阻止从较低级别构建同步器。支持。
源码
package java.util.concurrent.locks;
public abstract class AbstractQueuedSynchronizer
extends AbstractOwnableSynchronizer
implements java.io.Serializable {
private static final long serialVersionUID = 7373984972572414691L;
/**
* 创建一个新的{@code AbstractQueuedSynchronizer}实例,其初始同步状态为零。
*/
protected AbstractQueuedSynchronizer() { }
static final class Node {
static final Node SHARED = new Node();
static final Node EXCLUSIVE = null;
static final int CANCELLED = 1;
static final int SIGNAL = -1;
static final int CONDITION = -2;
static final int PROPAGATE = -3;
volatile int waitStatus;
volatile Node prev;
volatile Node next;
/**
* The thread that enqueued this node. Initialized on
* construction and nulled out after use.
*/
volatile Thread thread;
Node nextWaiter;
final boolean isShared() {
return nextWaiter == SHARED;
}
final Node predecessor() throws NullPointerException {
Node p = prev;
if (p == null)
throw new NullPointerException();
else
return p;
}
Node() { // Used to establish initial head or SHARED marker
}
Node(Thread thread, Node mode) { // Used by addWaiter
this.nextWaiter = mode;
this.thread = thread;
}
Node(Thread thread, int waitStatus) { // Used by Condition
this.waitStatus = waitStatus;
this.thread = thread;
}
}
private transient volatile Node head;
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);
Node pred = tail;
if (pred != null) {
node.prev = pred;
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
enq(node);
return node;
}
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);
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);
}
private void doReleaseShared() {
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;
}
if (h == head)
break;
}
}
private void setHeadAndPropagate(Node node, int propagate) {
Node h = head;
setHead(node);
if (propagate > 0 || h == null || h.waitStatus < 0 ||
(h = head) == null || h.waitStatus < 0) {
Node s = node.next;
if (s == null || s.isShared())
doReleaseShared();
}
}
// Utilities for various versions of acquire
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;
Node predNext = pred.next;
node.waitStatus = Node.CANCELLED;
if (node == tail && compareAndSetTail(node, pred)) {
compareAndSetNext(pred, predNext, null);
} else {
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; // help GC
}
}
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 {
compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
}
return false;
}
static void selfInterrupt() {
Thread.currentThread().interrupt();
}
private final boolean parkAndCheckInterrupt() {
LockSupport.park(this);
return Thread.interrupted();
}
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);
}
}
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; // help 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; // help 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; // help 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; // help 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; // help 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);
}
}
// Main exported methods
protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}
protected boolean tryRelease(int arg) {
throw new UnsupportedOperationException();
}
protected int tryAcquireShared(int arg) {
throw new UnsupportedOperationException();
}
protected boolean tryReleaseShared(int arg) {
throw new UnsupportedOperationException();
}
*/
protected boolean isHeldExclusively() {
throw new UnsupportedOperationException();
}
/**
* 在独占模式下获取,忽略中断。通过至少调用一次{@link
* 否则,线程将排队,并可能反复阻塞和解除阻塞,并调用{@link
* 此方法可用于实现方法{@link Lock#lock}。
*/
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
/**
* 以互斥方式获取,如果被中断则中止。通过首先检查中断状态,然后至少调用一次{@link
* 否则,线程将排队,并可能反复阻塞和解除阻塞,调用{@link
* 此方法可用于实现方法{@link Lock#lockInterruptably}。
*/
public final void acquireInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (!tryAcquire(arg))
doAcquireInterruptibly(arg);
}
/**
* 尝试以互斥方式进行获取,如果被中断则中止,如果给定的超时时间过去,则失败。
* 通过首先检查中断状态,然后至少调用一次{@link
* 否则,线程将排队(可能反复阻塞和解除阻塞),并调用{@link
* 此方法可用于实现方法{@link 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);
}
/**
* 以独占模式发布。如果{@link
* 此方法可用于实现方法{@link 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;
}
/**
* 以共享模式获取,忽略中断。通过首先至少调用一次{@link
* 否则,线程将排队,并可能反复阻塞和解除阻塞,并调用{@link
*/
public final void acquireShared(int arg) {
if (tryAcquireShared(arg) < 0)
doAcquireShared(arg);
}
/**
* 在共享模式下获取,如果中断则中止。
* 通过首先检查中断状态,然后至少调用一次{@link
* 否则,线程将排队,可能会反复阻塞和解除阻塞,并调用{@link
*/
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)
doAcquireSharedInterruptibly(arg);
}
/**
* 尝试以共享模式进行获取,如果被中断则中止,如果给定的超时时间过去,则失败。
* 通过首先检查中断状态,然后至少调用一次{@link
* 否则,线程将排队,并可能反复阻塞和解除阻塞,并调用{@link
*/
public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
return tryAcquireShared(arg) >= 0 ||
doAcquireSharedNanos(arg, nanosTimeout);
}
/**
* 以共享模式发布。如果{@link
*/
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();
return true;
}
return false;
}
// Queue inspection methods
/**
* 查询是否有任何线程正在等待获取。请注意,由于中断和超时导致的取消可能随时发生,因此{@code true}返回值不能保证任何其他线程都可以获取。
*/
public final boolean hasQueuedThreads() {
return head != tail;
}
/**
* 查询是否有任何线程争夺过该同步器;也就是说,如果获取方法曾经被阻止。
*/
public final boolean hasContended() {
return head != null;
}
/**
* 返回队列中的第一个(等待时间最长)线程,如果当前没有队列,则返回{@code null}。
* 在此实现中,此操作通常以固定的时间返回,但是如果其他线程正在同时修改队列,则可能在争用时进行迭代。
*/
public final Thread getFirstQueuedThread() {
return (head == tail) ? null : fullGetFirstQueuedThread();
}
private Thread fullGetFirstQueuedThread() {
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;
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;
}
/**
* 如果明显的第一个排队线程(如果存在)正在排他模式下等待,则返回{@code true}。
* 如果此方法返回{@code true},并且当前线程正尝试以共享模式进行获取(也就是说,此方法是从{@link
* 则可以确保当前线程不是第一个排队的线。仅在ReentrantReadWriteLock中用作启发式方法。
*/
final boolean apparentlyFirstQueuedIsExclusive() {
Node h, s;
return (h = head) != null &&
(s = h.next) != null &&
!s.isShared() &&
s.thread != null;
}
/**
* 查询是否有任何线程在等待获取比当前线程更长的时间。
* 调用此方法等效于(但可能比)更有效:{@code getFirstQueuedThread()!= Thread.currentThread()&& hasQueuedThreads()}
* 请注意,由于中断和超时导致的取消可能随时发生, {@code true}返回值不能保证其他一些线程将在当前线程之前获取。
* 同样,由于队列为空,此方法返回{@code false}后,另一个线程也有可能赢得竞争。
* 此方法设计为由公平同步器使用,以避免<a href="AbstractQueuedSynchronizer#barging">插入。
* 此类同步器的{@link
* 则其{@link
*/
public final boolean hasQueuedPredecessors() {
Node t = tail; // Read fields in reverse initialization order
Node h = head;
Node s;
return h != t &&
((s = h.next) == null || s.thread != Thread.currentThread());
}
// Instrumentation and monitoring methods
/**
* 返回等待获取的线程数的估计值。
* 该值只是一个估计值,因为在此方法遍历内部数据结构时,线程数可能会动态变化。
* 此方法设计用于监视系统状态,而不用于同步控制。
*/
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;
}
/**
* 返回一个包含可能正在等待以独占模式获取的线程的集合。
* 它具有与{@link
*/
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;
}
/**
* 返回一个包含可能正在共享模式下等待获取的线程的集合。
* 它具有与{@link
*/
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;
}
/**
* 返回标识此同步器及其状态的字符串。
* 括起来的状态包括字符串{@code“ State =”},后跟{@link
*/
public String toString() {
int s = getState();
String q = hasQueuedThreads() ? "non" : "";
return super.toString() +
"[State = " + s + ", " + q + "empty queue]";
}
// Internal support methods for Conditions
/**
* 如果某个节点(始终总是最初放置在条件队列中的一个节点)现在正等待在同步队列上重新获取,则返回true。
*/
final boolean isOnSyncQueue(Node node) {
if (node.waitStatus == Node.CONDITION || node.prev == null)
return false;
if (node.next != null) // If has successor, it must be on queue
return true;
/*
* node.prev can be non-null, but not yet on queue because
* the CAS to place it on queue can fail. So we have to
* traverse from tail to make sure it actually made it. It
* will always be near the tail in calls to this method, and
* unless the CAS failed (which is unlikely), it will be
* there, so we hardly ever traverse much.
*/
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) {
if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
return false;
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;
}
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;
}
}
// Instrumentation methods for conditions
/**
* 查询给定的ConditionObject是否使用此同步器作为其锁定。
*/
public final boolean owns(ConditionObject condition) {
return condition.isOwnedBy(this);
}
/**
* 查询是否有任何线程正在等待与此同步器关联的给定条件。
* 请注意,由于超时和中断可能随时发生,因此{@code true}返回并不保证将来的{@code signal}会唤醒任何线程。此方法主要设计用于监视系统状态。
*/
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();
}
/**
* {@link AbstractQueuedSynchronizer}的条件实现,用作{@link Lock}实现的基础。
* 此类的方法文档从锁定和条件用户的角度描述了机制,而不是行为规范。
* 此类的导出版本通常需要随附描述条件语义的文档,这些条件语义依赖于关联的{@code AbstractQueuedSynchronizer}的语义。
* 此类是可序列化的,但是所有字段都是瞬态的,因此反序列化条件没有侍者。
*
*/
public class ConditionObject implements Condition, java.io.Serializable {
private static final long serialVersionUID = 1173984872572414699L;
/** First node of condition queue. */
private transient Node firstWaiter;
/** Last node of condition queue. */
private transient Node lastWaiter;
/**
* Creates a new {@code ConditionObject} instance.
*/
public ConditionObject() { }
// Internal methods
/**
* Adds a new waiter to wait queue.
* @return its new wait node
*/
private Node addConditionWaiter() {
Node t = lastWaiter;
// If lastWaiter is cancelled, clean out.
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;
}
/**
* 删除并转移节点,直到命中不可取消的一个或为null。从信号中分离出来,部分鼓励编译器内联没有服务员的情况。
*/
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 methods
/**
* 将等待时间最长的线程(如果存在)从该条件的等待队列移至拥有锁的等待队列。
*/
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);
}
/**
* 实现不间断的条件等待。保存{@link
* 以保存的状态作为参数调用{@link
* 封锁直到发信号为止。
* 通过调用{@link
*/
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();
}
/*
* For interruptible waits, we need to track whether to throw
* InterruptedException, if interrupted while blocked on
* condition, versus reinterrupt current thread, if
* interrupted while blocked waiting to re-acquire.
*/
/** Mode meaning to reinterrupt on exit from wait */
private static final int REINTERRUPT = 1;
/** Mode meaning to throw InterruptedException on exit from wait */
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;
}
/**
* Throws InterruptedException, reinterrupts current thread, or
* does nothing, depending on mode.
*/
private void reportInterruptAfterWait(int interruptMode)
throws InterruptedException {
if (interruptMode == THROW_IE)
throw new InterruptedException();
else if (interruptMode == REINTERRUPT)
selfInterrupt();
}
/**
* 实现可中断条件等待。
* 如果当前线程被中断,则抛出InterruptedException。
* 保存{@link
* 以保存的状态作为参数调用{@link
* 阻塞直到发信号或被打断。通过调用{@link
* 如果在步骤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) // clean up if cancelled
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);
}
/**
* 实现定时条件等待。
* 如果当前线程被中断,则抛出InterruptedException。
* 保存{@link
* 以保存的状态作为参数调用{@link
* 阻塞直到发出信号,中断或超时为止。通过调用{@link
* 如果在步骤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();
}
/**
* 实现绝对定时条件等待。
* 如果当前线程被中断,则抛出InterruptedException。
* 保存{@link
* 以保存的状态作为参数调用{@link
* 阻塞直到发出信号,中断或超时为止。
* 通过调用{@link
* 如果在步骤4中被阻止而被中断,则抛出InterruptedException。
* 如果在步骤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;
}
/**
* 实现定时条件等待。
* 如果当前线程被中断,则抛出InterruptedException。
* 保存{@link
* 以保存的状态作为参数调用{@link
* 阻塞直到发出信号,中断或超时为止。
* 通过调用{@link
* 如果在步骤4中被阻止而被中断,则抛出InterruptedException。
* 如果在步骤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;
}
// support for instrumentation
/**
* Returns true if this condition was created by the given
* synchronization object.
*
* @return {@code true} if owned
*/
final boolean isOwnedBy(AbstractQueuedSynchronizer sync) {
return sync == AbstractQueuedSynchronizer.this;
}
/**
* 查询是否有任何线程在这种情况下等待。
*/
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;
}
/**
* 返回在此条件下等待的线程数的估计值。实现{@link
*/
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;
}
/**
* Implements {@link AbstractQueuedSynchronizer
* 返回一个包含可能正在等待此条件的线程的集合。实现{@link
*/
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 field. Used only by enq.
*/
private final boolean compareAndSetHead(Node update) {
return unsafe.compareAndSwapObject(this, headOffset, null, update);
}
/**
* CAS tail field. Used only by enq.
*/
private final boolean compareAndSetTail(Node expect, Node update) {
return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
}
/**
* CAS waitStatus field of a node.
*/
private static final boolean compareAndSetWaitStatus(Node node,
int expect,
int update) {
return unsafe.compareAndSwapInt(node, waitStatusOffset,
expect, update);
}
/**
* CAS next field of a node.
*/
private static final boolean compareAndSetNext(Node node,
Node expect,
Node update) {
return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
}
}