AQS初解
1.什么是AQS
AQS是JUC(java.util.concurrent)框架下的一个核心类(AbstractQueuedSynchronizer)是一个抽象的队列同步器,继承AbstractOwnableSynchronizer 是可以由一个线程独占的一种同步器可以保存占有当前同步器的线程,并提供 set、get方法。AbstractQueuedSynchronizer 是基于先进先出(FIFO)的等待队列实现的多线程间的同步工具。
AbstractQueuedSynchronizer 等待队列上的线程都会有一个对应的需要原子操作的 int 类型的数值表示线程当前的状态。AbstractQueuedSynchronizer 包含两部分内容,一部分是要求子类实现改变状态的方法,即需要子类实现获取锁和释放锁的逻辑;另一部分是实现线程进度等待队列自旋和阻塞,通知唤醒,出等待队列等功能。
AbstractQueuedSynchronizer 提供了两种同步策略,分别是独占模式和共享模式。
独占模式只允许一个线程获取锁。如果当前已经有一个线程获取锁了,那么其他线程获取锁时,都进入等待队列。
共享模式允许多个线程同时获取锁,但是不保证线程获取锁时一定能够成功。
AbstractQueuedSynchronizer 本身是没有获取锁和释放锁的具体实现,但是为了考虑到默写情况下,子类可能只需要提供一种策略模式,所以定义的获取锁和释放锁的方法是 protected,并且方法体只是抛出 UnsupportedOperationException 异常。
但是 AbstractQueuedSynchronizer 本身是负责维护等待队列和通知唤醒,所以一旦线程在共享模式下获取锁,AbstractQueuedSynchronizer 需要判断下一个等待线程是否需要也是需要获取锁。
AbstractQueuedSynchronizer 只维护一个双向链表作为等待队列,所以不同线程使用不同的同步策略时,他们都位于一个等待队列上。子类如果只需要一种同步策略,那么只需要实现一种同步策略。
锁定义了获取竞态条件(Condition)的接口,并且锁一般都依赖同步器实现许多功能,可能是为了方便锁的实现,所以在 AbstractQueuedSynchronizer 中有一个竞态条件的实现类 ConditionObject 的内部类。
java中的ReentrantLock、ReentrantReadWriteLock、Semaphore等都是基于AQS实现
2.AQS的实现逻辑
当一个线程来获取锁会尝试去使用CAS的方式修改AQS的state的状态字段,如果修改成功表示当前线程获取到锁,如果修改失败会将当前线程封装成一个Node几点放入队列中
1.在AQS存在一个state状态字段用于记录当前锁是否被某一个线程持有。默认为0 持有为1
// 标记为volatile
// 1.可见性 多个线程同时操作状态字段,一个线程修改后对其他线程可见
// 2.防止指令重排
private volatile int state;
protected final int getState() {
return state;
}
/**
* Sets the value of synchronization state.
* This operation has memory semantics of a {@code volatile} write.
* @param newState the new state value
*/
protected final void setState(int newState) {
state = newState;
}
2.在AQS中时使用一个双向链表(“CLH”(Craig、Landin 和 Hagersten)锁定队列的变体。)来存储等待的线程,AQS中的静态内部类Node是队列的节点,当一个线程尝试获取锁失败,会将这个线程封装成一个node节点放入队列中
static final class Node {
//分为共享模式和独占模式
//指示节点在共享模式下等待的标记
static final Node SHARED = new Node();
//指示节点在独占模式下等待的标记
static final Node EXCLUSIVE = null;
//以下是几个常量,标记当前节点的状态(waitStatus值)
//等待线程超时或者被中断、需要从同步队列中取消等待(也就是放弃资源的竞争),此状态不会在改变
static final int CANCELLED = 1;
//后继节点会处于等待状态,当前节点线程如果释放同步状态或者被取消则会通知后继节点线程,使后继节点线程的得以运行
static final int SIGNAL = -1;
/** 节点在等待队列中,线程在等待在Condition 上,其他线程对Condition调用singnal()方法后,该节点加入到同步队列中 */
static final int CONDITION = -2;//条件队列状态
/**
* 表示下一次共享式获取同步状态的时会被无条件的传播下去。
*/
static final int PROPAGATE = -3;
//当前节点的状态
volatile int waitStatus;
/**
* 前置节点
*/
volatile Node prev;
/**
* 后继节点
*/
volatile Node next;
/**
* 等待的线程
*/
volatile Thread thread;
/**
* 链接到下一个等待条件的节点,或特殊值 SHARED。
* 由于条件队列仅在以独占模式持有时才被访问,因此我们只需要一个简单的链接队列来在节点等待条件时持有它们。
* 然后,它们被转移到队列中以重新获取。
* 由于条件只能是独占的,因此我们通过使用特殊值来指示共享模式来保存字段。
*/
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;
}
}
在AQS中保存了当前等待队列的头节点和尾节点
/**
* 头节点
*/
private transient volatile Node head;
/**
* 尾节点
*/
private transient volatile Node tail;
3.基于ReentrantLock了解独占锁的实现流程
ReentrantLock 实现了Lock接口
public interface Lock {
/**
* 获取锁、如果锁不可用,则当前线程将出于线程调度目的而被禁用,并处于休眠状态,直到获得锁。
*/
void lock();
/**
* 获取锁、如果获取成功则返回
* 如果获取失败则被挂起 直到当前线程被中断
* 如果当前线程:
* 在进入此方法时设置了中断状态;
* 或在获取锁时被中断,则锁获取中断,
* 然后 InterruptedException 被抛出,当前线程的中断状态被清除。
*/
void lockInterruptibly() throws InterruptedException;
/**
* 尝试获取锁,此方法不会阻塞线程
*/
boolean tryLock();
/**
* 如果锁在给定的等待时间内处于空闲状态,并且当前线程未 中断,则获取锁。
* 如果在指定的时间内没有获取到锁,或被中断则放弃获取锁
*/
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
/**
* 释放锁
*/
void unlock();
/**
* 返回绑定到此Lock实例的新Condition实例。
*/
Condition newCondition();
}
1.ReentrantLock的lock方法
//调用sync的lock方法
public void lock() {
sync.lock();
}
//sync是ReentrantLock中的一个私有变量 是一个同步器
private final Sync sync;
//该同步器继承了AQS是ReentrantLock中的一个内部类
abstract static class Sync extends AbstractQueuedSynchronizer {
//该方法是一个抽象方法
abstract void lock();
}
//ReentrantLock分为公平锁和非公平锁构造器可以看出默认为非公平锁
public ReentrantLock() {
sync = new NonfairSync();
}
/**
* 可通过参数来构造公平锁和非公平锁
*/
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
FairSync和NonfairSync都继承了Sync实现了lock()方法
//非公平锁的lock()方法 (当前线程为要获取锁的线程)
final void lock() {
// 以CAS的方法尝试获取锁,如果成功则将当前线程保存起来,表示此线程正在持有锁
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
//公平锁的lock()方法(当前线程为要获取锁的线程)
final void lock() {
acquire(1);
}
// AQS中的方法 如果当前对象的状态为0则以原子的方式 改为1
// 如果当前状态值等于预期值,则以原子方式将同步状态设置为给定的更新值。
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
接下来看acquire(int arg)方法
//此方法为AQS中的方法 当前线程为要获取锁的线程
public final void acquire(int arg) {
//如果尝试获取锁失败并且没有将当前线程放到队列中则中断该线程
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
//设置当前线程为中断状态
selfInterrupt();
}
//AQS中的tryAcquire方法为不支持操作,具体的实现在子类中
protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}
//NonfairSync的tryAcquire(int arg)方法
protected final boolean tryAcquire(int acquires) {
//调用父类Sync中的方法
return nonfairTryAcquire(acquires);
}
final boolean nonfairTryAcquire(int acquires) {
//获取当前线程 要获取锁的线程
final Thread current = Thread.currentThread();
//获取当前同步器的状态
int c = getState();
//如果当前锁没有被任何一个线程持有
if (c == 0) {
//此时 acquires = 1 则尝试获取锁 如果获取成功则记录获取到锁的线程并返回成功
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
//如果此锁被某个线程持有 判断是否是当前线程 锁的重入
//每次锁重入 AQS的状态就会加一
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
// 超过锁最大的的重入次数 最大次数为2的31次方减一
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
//修改状态值 因为只有一个线程会进入到此方法 所以直接赋值不会有线程安全问题
setState(nextc);
return true;
}
return false;
}
//FairSync的tryAcquire(int arg)方法
protected final boolean tryAcquire(int acquires) {
//获取当前线程 要获取锁的线程
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
//查询是否有任何线程等待获取的时间超过当前线程。
//请注意,由于中断和超时可能随时发生取消, true 因此返回并不能保证在当前线程之前获得其他线程。同样,由于队列为空,因此 //在此方法返回 false后,另一个线程可能会赢得排队竞赛。
//返回:true 如果当前线程之前有一个排队的线程, false 当前线程位于队列的顶部或队列为空
public final boolean hasQueuedPredecessors() {
//当前队列的尾节点
Node t = tail;
//当前队列的头节点
Node h = head;
Node s;
//如果头节点不等于尾节点 将S设置为队列第一个线程 第一个线程不等于当前线程
//判断队列中的第一个要获取锁的线程是不是当前线程
return h != t &&
((s = h.next) == null || s.thread != Thread.currentThread());
}
addWaiter(Node mode)
//为当前线程和给定模式创建节点并使其排队
//当前mode为null是独占标记
private Node addWaiter(Node mode) {
//将当前线程封装为一个node节点 此时节点状态为默认状态 withState = 0
Node node = new Node(Thread.currentThread(), mode);
// 标记一个临时变量指向tail
Node pred = tail;
// 如果tail不为空
if (pred != null) {
//先标记node节点的前一个节点为tail node为线程内部变量 不会出现线程安全问题
node.prev = pred;
//以CAS的方式将尾部指针指向node节点
if (compareAndSetTail(pred, node)) {
//将前节点的next指向node
pred.next = node;
return node;
}
}
enq(node);
return node;
}
//将此AQS对象的tail字段更新为update原子方法
private final boolean compareAndSetTail(Node expect, Node update) {
return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
}
//将节点插入队列,必要时进行初始化。返回此节点的前一节点
private Node enq(final Node node) {
//循环将节点插入队列 直到成功
for (;;) {
Node t = tail;
//如果tail为空初始化一个节点 空节点线程信息为空 ws = 0;
if (t == null) { // Must initialize
if (compareAndSetHead(new Node()))
tail = head;
} else {
//先标记node节点的前一个节点为tail node为线程内部变量 不会出现线程安全问题
node.prev = t;
//以CAS的方式将尾部指针指向node节点
if (compareAndSetTail(t, node)) {
t.next = node;
//返回此节点的前一节点
return t;
}
}
}
}
private final boolean compareAndSetHead(Node update) {
return unsafe.compareAndSwapObject(this, headOffset, null, update);
}
acquireQueued(final Node node, int arg)
//以独占不间断模式获取已在队列中的线程。由条件等待方法以及获取使用。
// arg参数为1
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
//循环
for (;;) {
//node节点的前一个节点
final Node p = node.predecessor();
//表明当前线程排在队列中的第一位 尝试去获取锁
if (p == head && tryAcquire(arg)) {
//获取锁成功设置头节点
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
//设置当前节点的前一个结点为-1状态并挂起当前线程
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
//获取锁失败或者挂起线程失败了 将当前线程节点从队列中移除
if (failed)
cancelAcquire(node);
}
}
//设置头节点
private void setHead(Node node) {
head = node;
node.thread = null;
node.prev = null;
}
//检查并更新获取失败的节点的状态。如果线程应阻塞,则返回 true。这是所有采集环路中的主要信号控制。需要 pred == node.prev。
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
//获取前一节点的withState
int ws = pred.waitStatus;
// 前一节点的ws为 Node.SIGNAL(-1) 表明node为挂起状态
if (ws == Node.SIGNAL)
/*
* This node has already set status asking a release
* to signal it, so it can safely park.
*/
return true;
// 前一节点的ws > 0 为 1 表明前一节点的ws为取消状态
if (ws > 0) {
/*
* Predecessor was cancelled. Skip over predecessors and
* indicate retry.
*/
//循环查找前面不为取消状态的节点
do {
node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);
pred.next = node;
} else {
/*
* waitStatus must be 0 or PROPAGATE. Indicate that we
* need a signal, but don't park yet. Caller will need to
* retry to make sure it cannot acquire before parking.
*/
compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
}
return false;
}
//挂起当前线程
private final boolean parkAndCheckInterrupt() {
//挂起当前线程 如果被挂起的线程设置了中断状态会被直接唤醒
//设置了中断状态的线程不会被挂起
LockSupport.park(this);
//结束挂起后返回当前线程是否被中断 并清除线程的中断状态
return Thread.interrupted();
}
//取消正在进行的尝试获取的节点
//次此取消没有操作取消节点的 前置节点
//node为当前线程封装成的node节点
private void cancelAcquire(Node node) {
// Ignore if node doesn't exist
if (node == null)
return;
node.thread = null;
// Skip cancelled predecessors 跳过取消节点
// 找到该取消节点的上一个非取消状态节点
Node pred = node.prev;
while (pred.waitStatus > 0)
node.prev = pred = pred.prev;
// predNext is the apparent node to unsplice. CASes below will
// fail if not, in which case, we lost race vs another cancel
// or signal, so no further action is necessary.
// 取消节点的上一个非取消状态节点的下一节点
Node predNext = pred.next;
// Can use unconditional write instead of CAS here.
// After this atomic step, other Nodes can skip past us.
// Before, we are free of interference from other threads.
//将当前节点的ws设置取消
node.waitStatus = Node.CANCELLED;
// If we are the tail, remove ourselves.
// 如果取消的节点为尾部节点 将尾部节点设为 pred
if (node == tail && compareAndSetTail(node, pred)) {
//将pred的下一节点设为null
compareAndSetNext(pred, predNext, null);
} else {
// If successor needs signal, try to set pred's next-link
// so it will get one. Otherwise wake it up to propagate.
int ws;
//如果被取消的节点不是尾部节点,后续有节点需要被唤醒则需要设置前一节点为Node.SIGNAL
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 void unparkSuccessor(Node node) {
/*
* If status is negative (i.e., possibly needing signal) try
* to clear in anticipation of signal状态ling. It is OK if this
* fails or if status is changed by waiting thread.
*/
//唤醒了后续节点,清除当前节点的signal状态
int ws = node.waitStatus;
if (ws < 0)
compareAndSetWaitStatus(node, ws, 0);
/*
* Thread to unpark is held in successor, which is normally
* just the next node. But if cancelled or apparently null,
* traverse backwards from tail to find the actual
* non-cancelled successor.
*/
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);
}
2.ReentrantLock的lockInterruptibly() throws InterruptedException方法
//获取锁响应中断
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
//获取锁响应中断 AQS方法
//以独占模式获取,如果中断则中止。通过首先检查中断状态,然后至少调用一次 tryAcquire,成功时返回来实现。否则,线程将排队,可 能会重复阻塞和取消阻塞,直到 tryAcquire 成功或线程中断为止。此方法可用于实现方法 Lock.lockInterruptibly。
public final void acquireInterruptibly(int arg)
throws InterruptedException {
//如果线程为中断状态则直接抛出异常
if (Thread.interrupted())
throw new InterruptedException();
//尝试获取锁
if (!tryAcquire(arg))
//失败则排队
doAcquireInterruptibly(arg);
}
//以独占中断模式获取锁
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);
}
}
3.ReentrantLock的tryLock()方法
public boolean tryLock() {
return sync.nonfairTryAcquire(1);
}
//尝试获取锁
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
4.ReentrantLock的tryLock(long time, TimeUnit unit) throws InterruptedException方法
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
public final boolean tryAcquireNanos(int arg, long nanosTimeout)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
return tryAcquire(arg) ||
doAcquireNanos(arg, nanosTimeout);
}
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)
//spinForTimeoutThreshold 表示剩余的等待时间是需要自旋还是挂起当前线程
LockSupport.parkNanos(this, nanosTimeout);
//中断后抛出异常
if (Thread.interrupted())
throw new InterruptedException();
}
} finally {
if (failed)
//获取锁失败取消该节点
cancelAcquire(node);
}
}
5.ReentrantLock的 unlock()方法
public void unlock() {
sync.release(1);
}
//AQS方法
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
6.ReentrantLock其他方法
1.getHoldCount()方法
//查询当前线程对此锁的保留次数。
public int getHoldCount() {
return sync.getHoldCount();
}
//Sync方法 获取的AQS的state值
final int getHoldCount() {
return isHeldExclusively() ? getState() : 0;
}
2.isHeldByCurrentThread()方法
//查询此锁是否由当前线程持有
public boolean isHeldByCurrentThread() {
return sync.isHeldExclusively();
}
//Sync方法
protected final boolean isHeldExclusively() {
// While we must in general read state before owner,
// we don't need to do so to check if current thread is owner
return getExclusiveOwnerThread() == Thread.currentThread();
}
3.isLocked()
//查询此锁是否由任何线程持有。此方法设计用于监视系统状态,而不是用于同步控制。
public boolean isLocked() {
return sync.isLocked();
}
//Sync方法
final boolean isLocked() {
return getState() != 0;
}
4.isFair()
//判断当前锁是不是公平锁
public final boolean isFair() {
return sync instanceof FairSync;
}
5.getOwner()
//获取当前持有锁的线程 受保护方法只允许当前类及其子类调用
protected Thread getOwner() {
return sync.getOwner();
}
final Thread getOwner() {
return getState() == 0 ? null : getExclusiveOwnerThread();
}
6.hasQueuedThreads()
//查询是否有任何线程正在等待获取此锁。
public final boolean hasQueuedThreads() {
return sync.hasQueuedThreads();
}
//AQS方法
public final boolean hasQueuedThreads() {
return head != tail;
}
7.hasQueuedThread(Thread thread)
//查询给定线程是否正在等待获取此锁。
public final boolean hasQueuedThread(Thread thread) {
return sync.isQueued(thread);
}
//AQS方法
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;
}
8.getQueueLength()
//返回等待获取此锁的线程数的估计值。该值只是一个估计值,因为当此方法遍历内部数据结构时,线程数可能会动态变化。此方法设计用于 监视系统状态,而不是用于同步控制。
public final int getQueueLength() {
return sync.getQueueLength();
}
//AQS方法
public final int getQueueLength() {
int n = 0;
//从后往前遍历查找同步队列 包含取消状态的线程节点
for (Node p = tail; p != null; p = p.prev) {
if (p.thread != null)
++n;
}
return n;
}
9.getQueuedThreads()
//返回一个集合,该集合包含可能正在等待获取此锁的线程。由于在构造此结果时,实际的线程集可能会动态更改,因此返回的集合只是一个 尽力而为的估计值。返回的集合的元素没有特定的顺序。
protected Collection<Thread> getQueuedThreads() {
return sync.getQueuedThreads();
}
//AQS方法
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;
}
10.hasWaiters(Condition condition)
//查询是否有任何线程正在等待与此锁关联的给定条件。请注意,由于超时和中断可能随时发生,因此 true 返回并不能保证 future signal 会唤醒任何线程。此方法主要用于监视系统状态。
public boolean hasWaiters(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
}
//AQS方法
public final boolean hasWaiters(ConditionObject condition) {
if (!owns(condition))
throw new IllegalArgumentException("Not owner");
return condition.hasWaiters();
}
//查询给定的 ConditionObject 是否使用此同步器作为其锁。AQS方法
public final boolean owns(ConditionObject condition) {
// this为AQS对象
return condition.isOwnedBy(this);
}
//ConditionObject是AQS的一个内部类 内部类会有一个外部类的引用 判断sync是否是当前ConditionObject对象
//外部类的引用
//ConditionObject方法
final boolean isOwnedBy(AbstractQueuedSynchronizer sync) {
return sync == AbstractQueuedSynchronizer.this;
}
//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;
}
11.getWaitQueueLength(Condition condition)
//判断与当前锁相关联的条件对象有多少正在等待的线程
//返回在与此锁关联的给定条件下等待的线程数的估计值。请注意,由于超时和中断可能随时发生,因此估计值仅作为实际服务员数的上限。 此方法设计用于监视系统状态,而不是用于同步控制。
public int getWaitQueueLength(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
}
public final int getWaitQueueLength(ConditionObject condition) {
if (!owns(condition))
throw new IllegalArgumentException("Not owner");
return condition.getWaitQueueLength();
}
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;
}
12.getWaitingThreads(Condition condition)
//返回一个集合,该集合包含可能正在等待此条件的线程。
//返回一个集合,该集合包含那些可能正在等待与此锁关联的给定条件的线程。由于在构造此结果时,实际的线程集可能会动态更改,因此返 回的集合只是一个尽力而为的估计值。
protected Collection<Thread> getWaitingThreads(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
}
public final Collection<Thread> getWaitingThreads(ConditionObject condition) {
if (!owns(condition))
throw new IllegalArgumentException("Not owner");
return condition.getWaitingThreads();
}
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;
}