Semaphore.release()方法的底层原理
一、release() 方法代码解析
当调用 release() 方法时,实际调用的是 AQS 的 releaseShared(1) 方法。以下是其详细工作流程:
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();
return true;
}
return false;
}
1、Semaphore.release()
public void release() {
sync.releaseShared(1); // 调用 AQS 的共享模式方法
}
2、AQS.releaseShared(int arg)
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) { // 尝试释放许可
doReleaseShared(); // 唤醒等待线程
return true;
}
return false;
}
3、Semaphore.tryReleaseShared(int releases)
protected boolean tryReleaseShared(int releases) {
for (;;) {
int current = getState(); // 当前剩余许可数
int next = current + releases; // 计算新的许可数
if (next < current) {
throw new Error("Maximum permit count exceeded"); // 防止溢出
}
if (compareAndSetState(current, next)) { // CAS 更新 state
return true; // 成功释放许可
}
}
}
4、AQS.doReleaseShared()
private void doReleaseShared() {
for (;;) {
Node h = head; // 获取队列头节点
if (h != null && h != tail) { // 队列不为空
int ws = h.waitStatus;
if (ws == Node.SIGNAL) { // 需要唤醒后继节点
if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0)) {
continue; // CAS 失败,重试
}
unparkSuccessor(h); // 唤醒后继节点
} else if (ws == 0 && !compareAndSetWaitStatus(h, 0, Node.PROPAGATE)) {
continue; // CAS 失败,重试
}
}
if (h == head) { // 头节点未变化,退出循环
break;
}
}
}
二、release() 的工作流程
当调用 release() 方法时,实际调用的是 AQS 的 releaseShared(1) 方法。以下是其详细工作流程:
(1)、增加许可数
1、调用 tryReleaseShared(arg):
tryReleaseShared(arg) 是 AQS 的模板方法,由 Semaphore 实现。
在 Semaphore 中,tryReleaseShared(arg) 的逻辑是通过 int next = current + releases; 操作将 state 增加 1。
2、CAS 操作:
使用 compareAndSetState(current, next) 方法原子性地更新 state 变量。
如果 CAS 成功,表示线程成功释放许可;否则,重试。
(2)、唤醒等待线程
1、检查等待队列:
如果 CLH 队列中有等待的线程,AQS 会唤醒队列中的第一个有效节点(线程)。
被唤醒的线程会重新尝试获取许可。
2、传播唤醒:
- 在共享模式下,AQS 会传播唤醒信号,确保所有等待的线程都有机会获取许可。
Semaphore.release()方法的底层原理的更多相关文章
- HashMap底层原理分析(put、get方法)
1.HashMap底层原理分析(put.get方法) HashMap底层是通过数组加链表的结构来实现的.HashMap通过计算key的hashCode来计算hash值,只要hashCode一样,那ha ...
- KVO-基本使用方法-底层原理探究-自定义KVO-对容器类的监听
书读百变,其义自见! 将KVO形式以代码实现呈现,通俗易懂,更容易掌握 :GitHub -链接如果失效请自动搜索:https://github.com/henusjj/KVO_base 代码中有详 ...
- 红黑树规则,TreeSet原理,HashSet特点,什么是哈希值,HashSet底层原理,Map集合特点,Map集合遍历方法
==学习目标== 1.能够了解红黑树 2.能够掌握HashSet集合的特点以及使用(特点以及使用,哈希表数据结构) 3.能够掌握Map集合的特点以及使用(特点,常见方法,Map集合的遍历) 4.能够掌 ...
- 利用Redisson实现分布式锁及其底层原理解析
Redis介绍 参考地址:https://blog.csdn.net/turbo_zone/article/details/83422215 redis是一个key-value存储系统.和Memcac ...
- iOS底层原理总结 - 探寻block的本质(一)
面试题 block的原理是怎样的?本质是什么? __block的作用是什么?有什么使用注意点? block的属性修饰词为什么是copy?使用block有哪些使用注意? block在修改NSMu ...
- Java面试底层原理
面试发现经常有些重复的面试问题,自己也应该学会记录下来,最好自己能做成笔记,在下一次面的时候说得有条不紊,深入具体,面试官想必也很开心.以下是我个人总结,请参考: HashSet底层原理:(问了大几率 ...
- Java8线程池ThreadPoolExecutor底层原理及其源码解析
小侃一下 日常开发中, 或许不会直接new线程或线程池, 但这些线程相关的基础或思想是非常重要的, 参考林迪效应; 就算没有直接用到, 可能间接也用到了类似的思想或原理, 例如tomcat, jett ...
- 关于 ReentrantLock 中锁 lock() 和解锁 unlock() 的底层原理浅析
关于 ReentrantLock 中锁 lock() 和解锁 unlock() 的底层原理浅析 如下代码,当我们在使用 ReentrantLock 进行加锁和解锁时,底层到底是如何帮助我们进行控制的啦 ...
- 【T-SQL进阶】02.理解SQL查询的底层原理
本系列[T-SQL]主要是针对T-SQL的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础]02.联接查询 [T-SQL基础]03.子查询 [T-SQL基础]04.表表达式 ...
- HashMap的底层原理
简单说: 底层原理就是采用数组加链表: 两张图片很清晰地表明存储结构: 既然是线性数组,为什么能随机存取?这里HashMap用了一个小算法,大致是这样实现: // 存储时: int hash = ke ...
随机推荐
- 基于Redis组件的特性,实现一个分布式限流
分布式---基于Redis进行接口IP限流 场景 为了防止我们的接口被人恶意访问,比如有人通过JMeter工具频繁访问我们的接口,导致接口响应变慢甚至崩溃,所以我们需要对一些特定的接口进行IP限流,即 ...
- Pycharm:鼠标滚动控制字体大小
Pycharm字体放大的设置 1.File -> setting -> Keymap ->在搜寻框中输入:increase -> Increase Font Size(双击) ...
- Kotlin:【set集合】集合创建、可变集合mutableSetOf、集合转换(List转换成Set,去掉重复元素)、distinct快捷去重函数、数组
- uni-app封装网络请求
在项目下创建一个文件夹https 然后在文件夹下面创建两个文件api.js request.js api.js 用于存放项目的请求接口 request.js 用于存放封装的请求接口get post 在 ...
- ThreeJs-13效果合成与后期处理
一.合成效果原理与设置 什么是效果合成,就是可以把一些效果经过后期处理再放出来 原来的物体是直接通过render渲染出来,而现在则是经过一条render通道,可以处理也可以叠加处理后再放出来 首先正常 ...
- Idea报错 【cannot access com.xxx】的【解决办法】
正常操作代码,一个类突然标红,提示 cannot access com.xxx . 执行下面操作,执行完后项目变为正常 但是如果是你代码存在异常,可不是清缓存就能解决了,就要靠自己了哈哈 第一步Fil ...
- [ZJOI2019] 语言 题解
不愧是 \(ZJOI\),<最可做的一道题>都让人一头雾水-- 首先将问题转化到链上. 可以将总共的组数转化为每个点可以到达的城市. 明显给每个点建一棵动态开点线段树,维护可以和他通商的点 ...
- QT5笔记:7. 自定义类、自定义信号及类的元对象信息
自定义的QPerson类,需要继承 QObject类 qperson.h头文件 #ifndef QPERSON_H #define QPERSON_H #include <QObject> ...
- zabbix - [03] 安装部署
参考:https://www.yuque.com/fenghuo-tbnd9/ffmkvs zabbix6要求操作系统为Centos8,所以一开始安装部署的时候发现少了zabbix-server-my ...
- Sqoop - 使用场景
Oracle >> HDFS sqoop import --connect jdbc:oracle:thin:@<oracle_host>:<oracle_port> ...