前言
AQS
是Semaphore
、ReentrantReadWriteLock
、ReentrantLock
、CountDownLatch
等并发类
底层的实现,点开上面说的并发类的源码我们可以看到,它们自身的实现很少,基本上都是在AQS
下实现的。面试的
时候上述所说的并发工具都会问到,但一般我们只关注它们的用法与区别,很少关注其实现。今天这篇文章,我们以
ReentrantLock
为基础,来看AQS
是如何实现的ReentrantLock
。
AQS
AQS
AQS源码分析
Node 节点
锁的获取与释放
enq 与 addWaiter
/**
* Inserts node into queue, initializing if necessary. See picture above.
* @param node the node to insert
* @return node's predecessor
*/
private Node enq(Node node) {
for (;;) {
// 获取尾部节点
Node oldTail = tail;
//
if (oldTail != null) {
//设置插入节点的pre节点为旧节点
node.setPrevRelaxed(oldTail);
//CAS 设置尾部节点,循环到成功为止
if (compareAndSetTail(oldTail, node)) {
//设置旧节点next为插入的节点node
oldTail.next = node;
//返回旧节点
return oldTail;
}
} else {
//尾部节点为null,初始化队列
initializeSyncQueue();
}
}
}
/**
* Creates and enqueues node for current thread and given mode.
*
* @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared
* @return the new node
*/
private Node addWaiter(Node mode) {
Node node = new Node(mode);
for (;;) {
Node oldTail = tail;
if (oldTail != null) {
node.setPrevRelaxed(oldTail);
if (compareAndSetTail(oldTail, node)) {
oldTail.next = node;
return node;
}
} else {
initializeSyncQueue();
}
}
}
enq
与 addWaiter
业务逻辑相同,只是返回的节点不同,enq
返回旧的尾节点,addWaiter
返回当前节点。