一、定义
release(int) 是 AQS(AbstractQueuedSynchronizer)中的一个核心方法,用于在独占模式下释放同步状态。如果释放成功,则会唤醒等待队列中的后继节点,使其有机会获取同步状态
1、release(int) 方法的作用
-
功能:释放同步状态(独占模式),并唤醒等待队列中的后继节点
-
返回值:如果成功释放同步状态,则返回 true;否则返回 false
二、release(int) 方法的源码
以下是 release(int) 方法的源码及其详细解析:
public final boolean release(int arg) {if (tryRelease(arg)) { // 尝试释放同步状态// 队列头节点Node h = head;// 头节点什么时候是空?没有发生锁竞争,没有竞争线程创建哨兵节点// 条件成立说明阻塞队列有等待线程,需要唤醒 head 节点后面的线程if (h != null && h.waitStatus != 0) {unparkSuccessor(h); // 唤醒后继节点}return true;}return false;
}
1、tryRelease(int arg) 方法
-
作用:尝试释放同步状态,由子类实现。
-
返回值:如果成功释放同步状态,则返回 true;否则返回 false。
-
示例:
- 子类需要重写此方法以实现具体的同步逻辑
2、unparkSuccessor(Node node) 方法
-
作用:唤醒当前节点的后继节点。
-
参数:
-
node:当前节点(通常是头节点)
// 找到队列中距离 head 最近的一个没取消的 Node,unpark唤醒线程恢复其运行private void unparkSuccessor(Node node) {// 当前节点的状态int ws = node.waitStatus;if (ws < 0) {// 【尝试重置状态为 0】,因为当前节点要完成对后续节点的唤醒任务了,不需要 -1 了compareAndSetWaitStatus(node, ws, 0); }// 找到需要 unpark 的节点,当前节点的下一个Node s = node.next;if (s == null || s.waitStatus > 0) { // 如果后继节点为空或已取消不能唤醒,则从队尾开始查找,需要找到距离头节点最近的非取消的节点s = null;for (Node t = tail; t != null && t != node; t = t.prev) {// 说明当前线程状态需要被唤醒if (t.waitStatus <= 0) {// 置换引用s = t;}}}// 【找到合适的可以被唤醒的 node,则唤醒线程】if (s != null) {LockSupport.unpark(s.thread); }}
-
3、compareAndSetWaitStatus(Node node, int expect, int update) 方法
-
作用:通过 CAS 操作更新节点的 waitStatus。
-
源码:
4、LockSupport.unpark(Thread thread) 方法
-
作用:唤醒指定的线程。
-
源码:
5、release(int) 方法的执行流程
1、调用 tryRelease(int) 尝试释放同步状态。
2、如果成功,则检查头节点是否存在且 waitStatus 不为 0。
3、如果满足条件,则调用 unparkSuccessor(Node) 唤醒后继节点。
4、返回 true 表示释放成功;否则返回 false。
三、总结