AQS的Condition
节点转移
await方法等待signal方法或transferAfterCancelledWait方法把节点从Condition队列转移到AQS队列后执行
这是场景1的情况
等待线程
public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implement java.io.Serializable {
static final class Node {
public final void await() throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
Node node = addConditionWaiter();//添加到等待队列,也就是Condition队列,初始化时完成标志一定是未设置的
int savedState = fullyRelease(node); //释放资源
int interruptMode = 0;
while (!isOnSyncQueue(node)) { //查询完成状态,完成状态是判断是否已经不在等待队列中,所以这个条件相当于判断了两个条件(完成状态+是否在等待队列)
LockSupport.park(this); //调用等待函数挂起线程
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) //判断是否发生了中断,发生中断就尝试把节点从Condition队列转移到AQS队列后执行
break;
}
if (acquireQueued(node, savedState) && interruptMode != THROW_IE) //排队等待获取资源
interruptMode = REINTERRUPT;
if (node.nextWaiter != null)
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);
}
}
}
工作线程
- signal方法
public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implement java.io.Serializable {
public class ConditionObject implements Condition, java.io.Serializable {
public final void signal() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
Node first = firstWaiter;//获取Node
if (first != null)
doSignal(first);
}
private void doSignal(Node first) {
do {
if ( (firstWaiter = first.nextWaiter) == null)
lastWaiter = null;
first.nextWaiter = null;
} while (!transferForSignal(first) &&
(first = firstWaiter) != null);
}
final boolean transferForSignal(Node node) {
if (!compareAndSetWaitStatus(node, Node.CONDITION, 0)) //设置完成状态+节点从等待队列移出
return false;
Node p = enq(node);//从Condition队列转移到AQS队列
int ws = p.waitStatus;
if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
LockSupport.unpark(node.thread);//从队列中移除成功则唤醒线程
return true;
}
}
}
- checkInterruptWhileWaiting方法
public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implement java.io.Serializable {
public class ConditionObject implements Condition, java.io.Serializable {
private int checkInterruptWhileWaiting(Node node) {
return Thread.interrupted() ? //发生中断
(transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :
0;
}
//转移节点
final boolean transferAfterCancelledWait(Node node) {
if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {//设置完成状态+节点从等待队列移出
enq(node);//从Condition队列转移到AQS队列
return true;
}
while (!isOnSyncQueue(node))
Thread.yield();
return false;
}
}
}
1和2都可能发生节点转移,必须保证只有一个可以成功
这是场景2中类型2的情况
只有compareAndSetWaitStatus(node, Node.CONDITION, 0)执行成功的线程才能执行转移操作
节点转移后续处理
无论是被中断唤醒还是被signal方法唤醒,最终节点都转移到了AQS队列,所以只需要调用acquireQueued排队取出节点来执行就行了
public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implement java.io.Serializable {
public class ConditionObject implements Condition, java.io.Serializable {
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) //acquireQueued方法排队等待执行
interruptMode = REINTERRUPT;
if (node.nextWaiter != null)
unlinkCancelledWaiters(); //清除Condition队列中被CANCEL的节点
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);//中断处理
}
}
}
中断处理
public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implement java.io.Serializable {
public class ConditionObject implements Condition, java.io.Serializable {
//记录中断类型
private int checkInterruptWhileWaiting(Node node) {
return Thread.interrupted() ? //发生中断
(transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) : //转移发生在中断后:THROW_IE
//转移发生在signal方法:REINTERRUPT
0;
}
//判断转移发生在中断后还是signal方法
final boolean transferAfterCancelledWait(Node node) {
if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
enq(node);
return true;
}
while (!isOnSyncQueue(node))
Thread.yield();
return false;
}
//中断处理
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; //如果在acquireQueued方法中发生中断 & 节点转移发生在signal方法
if (node.nextWaiter != null)
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);//中断处理
}
//中断处理
private void reportInterruptAfterWait(int interruptMode)
throws InterruptedException {
if (interruptMode == THROW_IE)//转移发生在中断后抛出中断异常
throw new InterruptedException();
else if (interruptMode == REINTERRUPT) //转移发生在signal方法设置中断标志
selfInterrupt();
}
}
}
中断发生有三种情况
- 中断发生的时候节点还没有转移
- 中断发生的时候节点已经由signal方法转移
- 中断发生在AQS队列中排队等待执行的过程中
1情况抛出中断异常
2,3情况只是设置线程的中断标志