Condition
一、概述

Condition就是维护一个条件队列,当AQS的线程在lock()内Condition.await()后,该线程会释放锁,然后进入Condition的条件队列,当别的线程Condition.signal()唤醒他后,他会进入AQS的同步队列等待获得锁
核心方法:await()、signal()、signalAll()
二、源码
1、接口
public interface Condition {
//当前线程在接到信号或中断之前一直处于等待状态
void await() throws InterruptedException;
//当前线程在接到信号或中断之前一直处于等待状态,如果超时则返回false
boolean await(long time, TimeUnit unit) throws InterruptedException;
//当前线程在接到信号或中断之前一直处于等待状态,如果超时则返回-1,没超时就返回剩余的等待时间
long awaitNanos(long nanosTimeout) throws InterruptedException;
//当前线程在接到信号或中断之前一直处于等待状态,如果超过最后期限则返回false
boolean awaitUntil(Date deadline) throws InterruptedException;
//无法中断的等待
void awaitUninterruptibly();
//唤醒一个等待线程,线程必须先获得锁
void signal();
//唤醒所有等待线程,能返回的线程必须获取相关的锁
void signalAll();
}
2、属性
//队列的首节点 private transient Node firstWaiter; //队列的尾节点 private transient Node lastWaiter; //代表线程是在 signal 后被中断的 private static final int REINTERRUPT = 1; //代表线程是在 signal 前被中断的 private static final int THROW_IE = -1;
3、私有方法
//添加lastWaiter
private Node addConditionWaiter() {
Node t = lastWaiter;
//如果lastWaiter是取消状态
if (t != null && t.waitStatus != Node.CONDITION) {
//向前清理取消状态的waiter
unlinkCancelledWaiters();
t = lastWaiter;
}
//创建新节点,作为lastWaiter
Node node = new Node(Thread.currentThread(), Node.CONDITION);
if (t == null)
firstWaiter = node;
else
t.nextWaiter = node;
lastWaiter = node;
return node;
}
//向前清理取消状态的waiter
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;
}
}
//删除或者转移节点到同步队列中,直到获取的节点是不可取消节点,或者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);
}
//确认线程的中断情况
private int checkInterruptWhileWaiting(Node node) {
return Thread.interrupted() ? (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) : 0;
}
//根据interruptMode来确定是应该抛出InterruptedException还是继续中断
private void reportInterruptAfterWait(int interruptMode)
throws InterruptedException {
if (interruptMode == THROW_IE)
throw new InterruptedException();
else if (interruptMode == REINTERRUPT)
selfInterrupt();
}
4、公共方法
public ConditionObject() { }
public final void signal() {
//只有用到condition才需要实现,判断当前线程是否获得独占锁
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);
}
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();
}
public final void await() throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
Node node = addConditionWaiter();
//放弃所有持有的锁
int savedState = fullyRelease(node);
int interruptMode = 0;
//阻塞判断,当前node是不是在同步队列时,不在同步队列那么就park当前线程
while (!isOnSyncQueue(node)) {
LockSupport.park(this);
//如果被中断了,则检测中断
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
}
//这是此节点已经在同步队列中了
//在队列中获取锁,并判断当前的interruptMode不为-1,即不是抛出异常
if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
//把中断类型设置为,重新中断,意味在线程获得锁的时候,重新中断线程
interruptMode = REINTERRUPT;
if (node.nextWaiter != null) // clean up if cancelled
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);
}
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();
}
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;
}
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;
}
5、辅助方法
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;
}
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;
}
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;
}

浙公网安备 33010602011771号