一、定义

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. canal源码分析简介-3

    5.0 store模块  2018-10-08 23:14:58  8,328 7 1 store模块简介 store模块用于binlog事件的存储 ,目前开源的版本中仅实现了Memory内存模式.官 ...

  2. 数组 & 结构 & 位域 & 联合 & 枚举 & typedef

    C语言提供的五种自定义的构造数据类型: 数组: 是处理同一名字下的不同类型变量的结合体 结构: 是一种归在同一名字下相关的不同类型变量的结合,也可称为不同数据类型的集成体 位域:允许按为访问数据成员的 ...

  3. Linux软连接与硬链接的概念

  4. JavaScript 中的组合继承 :ES5 与 ES6 中最近似的写法

    JavaScript 的继承写法较多,在此并不一一讨论,仅对最常用的组合式继承做一个说明: 组合式继承主要利用了原型链继承和构造函数继承. 一.ES5 中的写法 function Person(nam ...

  5. 一键部署,玩转AI!天翼云Llama 3大模型学习机来了!

    近日,Meta公司发布了其最新研发成果--开源大模型Llama 3,共包含Llama 3 8B和Llama 3 70B两种规格,参数量级分别为80亿与700亿,并表示这是目前同体量下性能最好的开源模型 ...

  6. Q:oracle解锁用户

    怎么查看oracle用户是否被锁 1.一般oracle数据库默认是10次尝试失败后锁住用户 1.查看FAILED_LOGIN_ATTEMPTS的值 select * from dba_profiles ...

  7. FLink15--滑动窗口--SlidingWindiwApp

    一.依赖 https://www.cnblogs.com/robots2/p/16048648.html 二.代码 概念:滑动窗口有两个参数,窗口大小20和滑动大小6,6秒滑一次,统计近20秒数据 前 ...

  8. 【COM3D2Mod 制作教程(4)】实战!制作身体部分(上)

    [COM3D2Mod 制作教程(4)]实战!制作身体部分(上) 教程介绍 现在正式进入实战教程环节,我会以我的实际制作过程详尽的教授每个细节,也因此受限于篇幅大小,"实战!制作身体部分&qu ...

  9. QT5笔记: 15. 其他显示组件的常用功能

    其他显示组件的常用功能 代码 #include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget ...

  10. 互联网和DeepSeak时代,获取信息这么容易,为什么我们还是学习不好?

    因为人性倾向于立即获得享受,而不是延迟获得享受,然而,学习就是延迟获得享受,所以,学习,其实是反人性的一种活动. 学习,特别是对知识的深入学习,其实需要付出大量的时间和精力,这个过程中必然伴随着各种各 ...