Condition接口的一个实现类ConditionObject是AQS的内部类,每个Condition对象都包含一个队列,这个队列是Condition对象实现等待/通知的关键。 与Object的监视器模型(synchronized)中一个对象拥有一个同步队列和等待队列不同的是,J.U.C中AQS拥有一个同步队列和多个等待队列。
await方法
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
)
unlinkCancelledWaiters();
if (interruptMode
!= 0)
reportInterruptAfterWait(interruptMode
);
}
查看addConditionWaiter方法,fullyRelease方法,isOnSyncQueue方法,checkInterruptWhileWaiting方法,acquireQueued方法,unlinkCancelledWaiters方法
addConditionWaiter方法
private Node
addConditionWaiter() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
Node t
= lastWaiter
;
if (t
!= null
&& t
.waitStatus
!= Node
.CONDITION
) {
unlinkCancelledWaiters();
t
= lastWaiter
;
}
Node node
= new Node(Node
.CONDITION
);
if (t
== null
)
firstWaiter
= node
;
else
t
.nextWaiter
= node
;
lastWaiter
= node
;
return node
;
}
注意:在独占模式下,nextWaiter表示等待队列中的后继节点;在共享模式下,nextWaiter用SHARED常量表示,表示同步队列的共享模式节点。 查看unlinkCancelledWaiters方法 此方法被await方法调用
fullyRelease方法
final int fullyRelease(Node node
) {
try {
int savedState
= getState();
if (release(savedState
))
return savedState
;
throw new IllegalMonitorStateException();
} catch (Throwable t
) {
node
.waitStatus
= Node
.CANCELLED
;
throw t
;
}
}
查看release方法 此方法被await方法调用
isOnSyncQueue方法
final boolean isOnSyncQueue(Node node
) {
if (node
.waitStatus
== Node
.CONDITION
|| node
.prev
== null
)
return false;
if (node
.next
!= null
)
return true;
return findNodeFromTail(node
);
}
查看findNodeFromTail方法 此方法被await方法,transferAfterCancelledWait方法调用
unlinkCancelledWaiters方法
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
;
}
}
findNodeFromTail方法
private boolean findNodeFromTail(Node node
) {
for (Node p
= tail
;;) {
if (p
== node
)
return true;
if (p
== null
)
return false;
p
= p
.prev
;
}
}
查看findNodeFromTail方法 此方法被isOnSyncQueue方法调用
checkInterruptWhileWaiting方法
private int checkInterruptWhileWaiting(Node node
) {
return Thread
.interrupted() ?
(transferAfterCancelledWait(node
) ? THROW_IE
: REINTERRUPT
) :
0;
}
查看transferAfterCancelledWait方法 此方法被await方法调用
transferAfterCancelledWait方法
final boolean transferAfterCancelledWait(Node node
) {
if (node
.compareAndSetWaitStatus(Node
.CONDITION
, 0)) {
enq(node
);
return true;
}
while (!isOnSyncQueue(node
))
Thread
.yield();
return false;
}
查看isOnSyncQueue方法 此方法被checkInterruptWhileWaiting方法调用
signal方法
public final void signal() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
Node first
= firstWaiter
;
if (first
!= null
)
doSignal(first
);
}
查看doSignal方法
doSignal方法
private void doSignal(Node first
) {
do {
if ( (firstWaiter
= first
.nextWaiter
) == null
)
lastWaiter
= null
;
first
.nextWaiter
= null
;
} while (!transferForSignal(first
) &&
(first
= firstWaiter
) != null
);
}
查看transferForSignal方法调用 此方法被signal方法调用
transferForSignal方法
final boolean transferForSignal(Node node
) {
if (!node
.compareAndSetWaitStatus(Node
.CONDITION
, 0))
return false;
Node p
= enq(node
);
int ws
= p
.waitStatus
;
if (ws
> 0 || !p
.compareAndSetWaitStatus(ws
, Node
.SIGNAL
))
LockSupport
.unpark(node
.thread
);
return true;
}
查看enq方法 此方法被doSignal方法调用
enq方法
private Node
enq(Node node
) {
for (;;) {
Node oldTail
= tail
;
if (oldTail
!= null
) {
node
.setPrevRelaxed(oldTail
);
if (compareAndSetTail(oldTail
, node
)) {
oldTail
.next
= node
;
return oldTail
;
}
} else {
initializeSyncQueue();
}
}
}
此方法被transferAfterCancelledWait方法,transferForSignal方法调用
signalAll方法
public final void signalAll() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
Node first
= firstWaiter
;
if (first
!= null
)
doSignalAll(first
);
}
查看doSignalAll方法
doSignalAll方法
private void doSignalAll(Node first
) {
lastWaiter
= firstWaiter
= null
;
do {
Node next
= first
.nextWaiter
;
first
.nextWaiter
= null
;
transferForSignal(first
);
first
= next
;
} while (first
!= null
);
}
查看transferForSignal方法 此方法被signalAll方法调用
awaitUninterruptibly方法
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();
}
查看addConditionWaiter方法,fullyRelease方法,isOnSyncQueue方法,acquireQueued方法 此方法被signalAll方法调用
回到顶部