bsp; cancelAcquire(node);
}
}
响应超时在自旋期间会计算还有多久超时,如果大于1ms就等待对应的时间,否则就继续自旋,同时响应中断
共享
共享式就是允许多个线程同时获取一定的资源,比如信号量、读锁就是用共享式实现的
其实共享式与独占式流程类似,只是尝试获取同步状态的实现不同
我们用个获取同步状态的方法来说明
共享式获取同步状态使用acquireShared
public final void acquireShared(int arg) {
if (tryAcquireShared(arg) < 0)
doAcquireShared(arg);
}
tryAcquireShared
尝试获取同步状态,参数arg表示获取多少同步状态,返回剩余可获取同步状态的数量
如果剩余可获取同步状态数量小于0 说明 未获取成功进入doAcquireShared
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);
}
}
响应中断、超时等方法也与独占式类似,只是有些设置细节不同
Condition
上文曾说过AQS充当阻塞(同步)队列,Condition来充当等待队列
AQS的内部类ConditionObject就是Condition的实现,它充当等待队列,用字段记录头尾节点
public class ConditionObject implements Condition{
//头节点
private transient Node firstWaiter;
//尾节点
private transient Node lastWaiter;
}
节点之间使用nextWait指向下一个节点,形成单向链表
同时提供await
系列方法来让当前线程进入等待,signal
系列方法来唤醒
public final void await() throws InterruptedException {
//响应中断
if (Thread.interrupted())
&n