返回
AQS 深度解析:共享锁揭秘
后端
2023-09-28 13:46:29
AQS 共享锁的奥秘
获取共享锁的过程与独占锁的过程在整体上非常相似,但其中也有一些关键的区别。在 acquireShared 方法中,AQS 会首先检查当前线程是否已经持有共享锁。如果已经持有,则直接增加共享锁计数器并返回。如果当前线程没有持有共享锁,则会尝试获取独占锁。如果能够成功获取独占锁,则会将其转换为共享锁并返回。如果获取独占锁失败,则会将当前线程加入到等待队列中,并阻塞等待其他线程释放共享锁。
public final void acquireShared(int arg) {
if (tryAcquireShared(arg) < 0)
doAcquireShared(arg);
}
public final int tryAcquireShared(int acquires) {
Thread current = Thread.currentThread();
if (exclusiveOwnerThread == current) {
int available = sharedCount;
if (available >= acquires) {
sharedCount = available - acquires;
return acquires;
}
}
return -1;
}
public final void doAcquireShared(int acquires) {
final Node node = addWaiter(Node.SHARED);
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquireShared(acquires) < 0) {
interrupted = Node.awaitLock(node, interrupted);
} else {
if (shouldParkAfterFailedAcquire(p, node))
interrupted = Node.parkAndCheckInterrupt();
failed = false;
return;
}
}
} finally {
if (failed)
cancelAcquire(node);
}
}
共享锁与独占锁的异同
通过对 AQS 共享锁获取过程的分析,我们可以发现它与独占锁的获取过程在整体上非常相似。它们都涉及到尝试获取锁、加入等待队列、阻塞等待等步骤。但是,它们之间也存在一些关键的区别。
- 共享锁可以同时被多个线程持有,而独占锁只能被一个线程持有。
- 获取共享锁时,如果当前线程已经持有共享锁,则直接增加共享锁计数器并返回。
- 获取独占锁时,如果当前线程已经持有共享锁,则需要先释放共享锁,然后再尝试获取独占锁。
总结
在本文中,我们深入分析了 AQS 共享锁的获取过程,并将其与独占锁的获取过程进行了比较。通过这种方式,我们对 AQS 的并发控制机制有了更加全面的理解。在实际的开发中,我们可以根据需要选择使用共享锁或独占锁来保护我们的共享资源,从而提高程序的并发性和安全性。