1 AbstractQueuedSynchronizer中的acquireShared方法
public final void acquireShared(int arg) {
if (tryAcquireShared(arg) < 0)
doAcquireShared(arg);
}
我们可以将acquireShared方法改写成另一种形式。
public final void acquireShared(int arg) {
// 尝试获取共享锁
if (tryAcquireShared(arg) >= 0)
return;
else
doAcquireShared(arg);
}
1.1 AbstractQueuedSynchronizer中的tryAcquireShared方法
子类中可以重写tryAcquireShared方法。
(1)返回值小于0:获取共享锁失败。
(2)返回值等于0:获取共享锁成功,之后再次尝试获取共享锁一定失败。
(3)返回值大于0:获取共享锁成功,之后再次尝试获取共享锁可能成功。
// 尝试获取共享锁
protected int tryAcquireShared(int arg) {
throw new UnsupportedOperationException();
}
1.2 AbstractQueuedSynchronizer中的doAcquireShared方法
private void doAcquireShared(int arg) {
// 为当前线程创建节点,并将这个节点插入到同步队列中
final Node node = addWaiter(Node.SHARED);
// failed等于true代表当前线程尚未获取共享锁
// failed等于false代表当前线程已经获取共享锁
boolean failed = true;
try {
// interrupted代表当前线程是否被中断
boolean interrupted = false;
// 自旋,直至当前线程已经获取共享锁或抛出异常
for (;;) {
// 获取node节点中的prev字段
final Node p = node.predecessor();
// 如果node节点中的prev字段等于头节点
if (p == head) {
// 尝试获取共享锁
int r = tryAcquireShared(arg);
if (r >= 0) {
// 运行到这里,说明当前线程已经获取共享锁
setHeadAndPropagate(node, r);
// 将原来的头节点中的next字段设为null
p.next = null; // help GC
if (interrupted)
// 恢复当前线程的中断状态
selfInterrupt();
failed = false;
return;
}
}
// 调用shouldParkAfterFailedAcquire方法判断是否应该阻塞当前线程
// shouldParkAfterFailedAcquire方法返回true,调用parkAndCheckInterrupt方法阻塞当前线程
// shouldParkAfterFailedAcquire方法返回false,继续循环
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
// 运行到这里,要么当前线程已经获取共享锁,要么抛出异常
// 如果抛出异常,调用cancelAcquire方法
if (failed)
cancelAcquire(node);
}
}
1.2.1 AbstractQueuedSynchronizer中的setHeadAndPropagate方法
// 传入的propagate是tryAcquireShared方法的返回值
private void setHeadAndPropagate(Node node, int propagate) {
Node h = head;
// 将头节点设为node节点,将node节点中的线程对象设为null,将node节点中的prev字段设为null
setHead(node);
if (propagate > 0 || h == null || h.waitStatus < 0 ||
(h = head) == null || h.waitStatus < 0) {
Node s = node.next;
// 如果node节点中的next字段等于null或node节点正在共享模式中等待
if (s == null || s.isShared())
doReleaseShared();
}
}
2 AbstractQueuedSynchronizer中的releaseShared方法
// releaseShared方法的返回值等于tryReleaseShared方法的返回值
public final boolean releaseShared(int arg) {
// 尝试释放共享锁
if (tryReleaseShared(arg)) {
doReleaseShared();
return true;
}
return false;
}
2.1 AbstractQueuedSynchronizer中的tryReleaseShared方法
子类中可以重写tryReleaseShared方法。
// 尝试释放共享锁
protected boolean tryReleaseShared(int arg) {
throw new UnsupportedOperationException();
}
2.2 AbstractQueuedSynchronizer中的doReleaseShared方法
setHeadAndPropagate方法和releaseShared方法都可能调用本方法。
private void doReleaseShared() {
// 自旋
for (;;) {
Node h = head;
// 如果头节点不等于null并且头节点不等于尾节点
if (h != null && h != tail) {
int ws = h.waitStatus;
// 如果头节点中的waitStatus等于-1,尝试将头节点中的waitStatus设为0
if (ws == Node.SIGNAL) {
if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
continue;
// 运行到这里,说明成功将头节点中的waitStatus设为0
// 唤醒后续节点中的线程对象
unparkSuccessor(h);
}
// 如果头节点中的waitStatus等于0,尝试将头节点中的waitStatus设为-3
else if (ws == 0 &&
!compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
continue;
}
// 如果头节点保持不变,跳出循环
if (h == head)
break;
}
}
网友评论