一、定义

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。

三、总结

AQS的release(int)方法底层源码的更多相关文章

  1. Java并发包源码学习之AQS框架(四)AbstractQueuedSynchronizer源码分析

    经过前面几篇文章的铺垫,今天我们终于要看看AQS的庐山真面目了,建议第一次看AbstractQueuedSynchronizer 类源码的朋友可以先看下我前面几篇文章: <Java并发包源码学习 ...

  2. Android开发之漫漫长途 Ⅵ——图解Android事件分发机制(深入底层源码)

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  3. 为什么很多类甚者底层源码要implements Serializable ?

    为什么很多类甚者底层源码要implements Serializable ? 在碰到异常类RuntimeException时,发现Throwable实现了 Serializable,还有我们平进的ja ...

  4. List-LinkedList、set集合基础增强底层源码分析

    List-LinkedList 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 继上一章继续讲解,上章内容: List-ArreyLlist集合基础增强底层源码分析:https:// ...

  5. 从底层源码浅析Mybatis的SqlSessionFactory初始化过程

    目录 搭建源码环境 POM依赖 测试SQL Mybatis全局配置文件 UserMapper接口 UserMapper配置 User实体 Main方法 快速进入Debug跟踪 源码分析准备 源码分析 ...

  6. Java泛型底层源码解析-ArrayList,LinkedList,HashSet和HashMap

    声明:以下源代码使用的都是基于JDK1.8_112版本 1. ArrayList源码解析 <1. 集合中存放的依然是对象的引用而不是对象本身,且无法放置原生数据类型,我们需要使用原生数据类型的包 ...

  7. HashMap和ConcurrentHashMap的区别,HashMap的底层源码

    HashMap本质是数组加链表,根据key取得hash值,然后计算出数组下标,如果多个key对应到同一个下标,就用链表串起来,新插入的在前面. ConcurrentHashMap在HashMap的基础 ...

  8. 总结HashSet以及分析部分底层源码

    总结HashSet以及分析部分底层源码 1. HashSet继承的抽象类和实现的接口 继承的抽象类:AbstractSet 实现了Set接口 实现了Cloneable接口 实现了Serializabl ...

  9. LInkedList总结及部分底层源码分析

    LInkedList总结及部分底层源码分析 1. LinkedList的实现与继承关系 继承:AbstractSequentialList 抽象类 实现:List 接口 实现:Deque 接口 实现: ...

  10. Vector总结及部分底层源码分析

    Vector总结及部分底层源码分析 1. Vector继承的抽象类和实现的接口 Vector类实现的接口 List接口:里面定义了List集合的基本接口,Vector进行了实现 RandomAcces ...

随机推荐

  1. struts2框架详解

    struts2框架(1)---struts2入门 struts2框架 如果你之前在MVC模式的时候一直都是通过servlet,获取和返回数据,那么现在开始学习struts2框架, Struts是一个实 ...

  2. Educated PG walkthrough Intermediate

    nmap 扫 到 80 22 dirsearch 扫描发现 ┌──(root㉿kali)-[~] └─# dirsearch -u http://192.168.167.13/ /usr/lib/py ...

  3. 云安全CIA:关键信息保证的三大支柱

    本文分享自天翼云开发者社区<云安全CIA:关键信息保证的三大支柱>,作者:每日知识小分享 随着云计算的迅速普及,云安全问题越来越受到关注.云安全涉及的范围广泛,涵盖了云端数据中心的物理安全 ...

  4. Idea下载插件报错

    报错内容Plugin Python was not installed: Cannot download 'https://plugins.jetbrains. 解决办法 file ->  se ...

  5. 为什么Raft算法是分布式系统的首选?

    背景 当今的数据中心和应用程序在高度动态的环境中运行,为了应对高度动态的环境,它们通过额外的服务器进行横向扩展,并且根据需求进行扩展和收缩.同时,服务器和网络故障也很常见. 因此,系统必须在正常操作期 ...

  6. [WC2014] 紫荆花之恋 题解

    啊啊啊啊啊啊啊啊啊啊啊我终于改完啦啊啊啊啊啊啊啊. 因为没有在最开始的时候将所有点设置为已经重构的,所以直接 \(R15-R70\) 间卡了两三天. 似乎也是我第一次大规模使用指针了. 这道题假如只有 ...

  7. [NOI2014] 购票 题解

    首先发现 \(p_x\times dis(x,y)+q_x\) 异常像是能斜率优化的样子,那先把求 \(f_x\) 的式子写出来(下设 \(d_x\) 表示 \(x\) 到根的距离): \[f_x=\ ...

  8. [IOI2020] 连接擎天树 题解

    第一道函数交互 \(+\ luogu\) 最劣解,这不得发篇博客鼓励一下. 引理 \(1\):若 \(p_{i,j}>0,p_{i,k}>0,p_{j,k}=0(i\ne j\ne k)\ ...

  9. [JOI 2020 Final] 火事 题解

    给一篇题解.(下面这张图是从 luogu 上粘贴的,因为不太会画图) 其中纵坐标为 \(t\),横坐标为 \(a_i\). 发现同颜色块只有平行四边形和直角梯形(等腰直角三角形)两种情况. 可以将直角 ...

  10. 解密prompt系列49. 回顾R1之前的思维链发展路线

    在所有人都在谈论R1的今天,作为算法也是有些千头万绪无从抓起.所以这一章先复盘,我先按照自己的思路来梳理下R1之前整个模型思维链的发展过程.下一章再展望主要去看RL在Agent上的一些尝试,毕竟Age ...