AQS的release(int)方法底层源码
一、定义
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)方法底层源码的更多相关文章
- Java并发包源码学习之AQS框架(四)AbstractQueuedSynchronizer源码分析
经过前面几篇文章的铺垫,今天我们终于要看看AQS的庐山真面目了,建议第一次看AbstractQueuedSynchronizer 类源码的朋友可以先看下我前面几篇文章: <Java并发包源码学习 ...
- Android开发之漫漫长途 Ⅵ——图解Android事件分发机制(深入底层源码)
该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...
- 为什么很多类甚者底层源码要implements Serializable ?
为什么很多类甚者底层源码要implements Serializable ? 在碰到异常类RuntimeException时,发现Throwable实现了 Serializable,还有我们平进的ja ...
- List-LinkedList、set集合基础增强底层源码分析
List-LinkedList 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 继上一章继续讲解,上章内容: List-ArreyLlist集合基础增强底层源码分析:https:// ...
- 从底层源码浅析Mybatis的SqlSessionFactory初始化过程
目录 搭建源码环境 POM依赖 测试SQL Mybatis全局配置文件 UserMapper接口 UserMapper配置 User实体 Main方法 快速进入Debug跟踪 源码分析准备 源码分析 ...
- Java泛型底层源码解析-ArrayList,LinkedList,HashSet和HashMap
声明:以下源代码使用的都是基于JDK1.8_112版本 1. ArrayList源码解析 <1. 集合中存放的依然是对象的引用而不是对象本身,且无法放置原生数据类型,我们需要使用原生数据类型的包 ...
- HashMap和ConcurrentHashMap的区别,HashMap的底层源码
HashMap本质是数组加链表,根据key取得hash值,然后计算出数组下标,如果多个key对应到同一个下标,就用链表串起来,新插入的在前面. ConcurrentHashMap在HashMap的基础 ...
- 总结HashSet以及分析部分底层源码
总结HashSet以及分析部分底层源码 1. HashSet继承的抽象类和实现的接口 继承的抽象类:AbstractSet 实现了Set接口 实现了Cloneable接口 实现了Serializabl ...
- LInkedList总结及部分底层源码分析
LInkedList总结及部分底层源码分析 1. LinkedList的实现与继承关系 继承:AbstractSequentialList 抽象类 实现:List 接口 实现:Deque 接口 实现: ...
- Vector总结及部分底层源码分析
Vector总结及部分底层源码分析 1. Vector继承的抽象类和实现的接口 Vector类实现的接口 List接口:里面定义了List集合的基本接口,Vector进行了实现 RandomAcces ...
随机推荐
- canal源码分析简介-3
5.0 store模块 2018-10-08 23:14:58 8,328 7 1 store模块简介 store模块用于binlog事件的存储 ,目前开源的版本中仅实现了Memory内存模式.官 ...
- 数组 & 结构 & 位域 & 联合 & 枚举 & typedef
C语言提供的五种自定义的构造数据类型: 数组: 是处理同一名字下的不同类型变量的结合体 结构: 是一种归在同一名字下相关的不同类型变量的结合,也可称为不同数据类型的集成体 位域:允许按为访问数据成员的 ...
- Linux软连接与硬链接的概念
- JavaScript 中的组合继承 :ES5 与 ES6 中最近似的写法
JavaScript 的继承写法较多,在此并不一一讨论,仅对最常用的组合式继承做一个说明: 组合式继承主要利用了原型链继承和构造函数继承. 一.ES5 中的写法 function Person(nam ...
- 一键部署,玩转AI!天翼云Llama 3大模型学习机来了!
近日,Meta公司发布了其最新研发成果--开源大模型Llama 3,共包含Llama 3 8B和Llama 3 70B两种规格,参数量级分别为80亿与700亿,并表示这是目前同体量下性能最好的开源模型 ...
- Q:oracle解锁用户
怎么查看oracle用户是否被锁 1.一般oracle数据库默认是10次尝试失败后锁住用户 1.查看FAILED_LOGIN_ATTEMPTS的值 select * from dba_profiles ...
- FLink15--滑动窗口--SlidingWindiwApp
一.依赖 https://www.cnblogs.com/robots2/p/16048648.html 二.代码 概念:滑动窗口有两个参数,窗口大小20和滑动大小6,6秒滑一次,统计近20秒数据 前 ...
- 【COM3D2Mod 制作教程(4)】实战!制作身体部分(上)
[COM3D2Mod 制作教程(4)]实战!制作身体部分(上) 教程介绍 现在正式进入实战教程环节,我会以我的实际制作过程详尽的教授每个细节,也因此受限于篇幅大小,"实战!制作身体部分&qu ...
- QT5笔记: 15. 其他显示组件的常用功能
其他显示组件的常用功能 代码 #include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget ...
- 互联网和DeepSeak时代,获取信息这么容易,为什么我们还是学习不好?
因为人性倾向于立即获得享受,而不是延迟获得享受,然而,学习就是延迟获得享受,所以,学习,其实是反人性的一种活动. 学习,特别是对知识的深入学习,其实需要付出大量的时间和精力,这个过程中必然伴随着各种各 ...