源码分析--Semaphore

告别手动连接!一键搞定Mumu模拟器与Android Studio的ADB配置 本文详细介绍了如何通过编写自动化脚本,一键完成Mumu模拟器与Android Studio的ADB连接配置。告别繁琐的手动命令输入,该脚本能智能检查环境、判断连接状态并自动处理端口转发,显著提升Android开发者的调试与测试效率。 阅读详情

概述

Semaphore 是并发包中的一个工具类,可理解为信号量。通常可以作为限流器使用,即限制访问某个资源的线程个数,比如用于限制连接池的连接数。

主要方法如下:
在这里插入图片描述
其中主要方法是 acquire() 和 release() 相关的一系列方法,它们的作用类似。

void acquire():从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。
void release():释放一个许可,将其返回给信号量。
int availablePermits():返回此信号量中当前可用的许可数。
boolean hasQueuedThreads():查询是否有线程正在等待获取。

源码分析

构造器

// 初始化 Semaphore,传入指定的许可数量,非公平
public Semaphore(int permits) {
    sync = new NonfairSync(permits);
}

// 初始化 Semaphore,传入指定的许可数量,指定是否公平
public Semaphore(int permits, boolean fair) {
    sync = fair ? new FairSync(permits) : new NonfairSync(permits);
}

构造器初始化了 Sync 变量,根据传入的 fair 值指定为 FairSync 或 NonFairSync。
内部嵌套类 Sync

abstract static class Sync extends AbstractQueuedSynchronizer {
    private static final long serialVersionUID = 1192457210091910933L;

    // 构造器,将父类 AQS 的 state 变量初始化为给定的 permits
    Sync(int permits) {
        setState(permits);
    }

    // 非公平方式尝试获取许可(减少 state 的值)
    final int nonfairTryAcquireShared(int acquires) {
        // 自旋操作
        for (;;) {
            // 获取许可值(state),并尝试 CAS 修改为减去后的结果
            int available = getState();
            int remaining = available - acquires;
            if (remaining < 0 ||
                compareAndSetState(available, remaining))
                return remaining;
        }
    }

    // 释放许可(增加 state 的值)
    protected final boolean tryReleaseShared(int releases) {
        for (;;) {
            // 操作与获取类似,不同的在于此处是增加 state 值
            int current = getState();
            int next = current + releases;
            if (next < current) // overflow
                throw new Error("Maximum permit count exceeded");
            if (compareAndSetState(current, next))
                return true;
        }
    }

	//TODO...
}

Sync 类继承自 AQS,并重写了 AQS 的 tryReleaseShared 方法,其中获取和释放许可分别对应的是对 AQS 中 state 值的减法和加法操作。

NonFairSync (非公平版本实现)

static final class NonfairSync extends Sync {
    private static final long serialVersionUID = -2694183684443567898L;

    // 调用父类 Sync 的构造器来实现
    NonfairSync(int permits) {
        super(permits);
    }
    // 重写 AQS 的 tryAcquireShared 方法,代码实现在父类 Sync 中
    protected int tryAcquireShared(int acquires) {
        return nonfairTryAcquireShared(acquires);
    }
}

FairSync (公平版本实现)

static final class FairSync extends Sync {
    private static final long serialVersionUID = 2014338818796000944L;

    // 构造器调用父类 Sync 的构造器来实现
    FairSync(int permits) {
        super(permits);
    }

    // 重写 AQS 的 tryAcquireShared 方法,尝试获取许可(permit)
    protected int tryAcquireShared(int acquires) {
        for (;;) {
            // 若队列中有其他线程等待,则获取失败(这就是体现“公平”的地方)
            if (hasQueuedPredecessors())
                return -1;
            // 获取当前的许可值
            int available = getState();
            // 计算剩余值
            int remaining = available - acquires;
            if (remaining < 0 ||
                compareAndSetState(available, remaining))
                return remaining;
        }
    }
}

主要方法:

// 获取一个许可(可中断)
public void acquire() throws InterruptedException {
    sync.acquireSharedInterruptibly(1);
}

// 获取一个许可(不响应中断)
public void acquireUninterruptibly() {
    sync.acquireShared(1);
}

// 尝试获取一个许可
public boolean tryAcquire() {
    return sync.nonfairTryAcquireShared(1) >= 0;
}

// 尝试获取一个许可(有超时等待)
public boolean tryAcquire(long timeout, TimeUnit unit)
    throws InterruptedException {
    return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}

// 释放一个许可
public void release() {
    sync.releaseShared(1);
}
// 获取指定数量的许可(可中断)
public void acquire(int permits) throws InterruptedException {
    if (permits < 0) throw new IllegalArgumentException();
    sync.acquireSharedInterruptibly(permits);
}

// 获取指定数量的许可(不可中断)
public void acquireUninterruptibly(int permits) {
    if (permits < 0) throw new IllegalArgumentException();
    sync.acquireShared(permits);
}

// 尝试获取指定数量的许可
public boolean tryAcquire(int permits) {
    if (permits < 0) throw new IllegalArgumentException();
    return sync.nonfairTryAcquireShared(permits) >= 0;
}

// 尝试获取指定数量的许可(有超时等待)
public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
    throws InterruptedException {
    if (permits < 0) throw new IllegalArgumentException();
    return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout));
}

// 释放指定数量的许可
public void release(int permits) {
    if (permits < 0) throw new IllegalArgumentException();
    sync.releaseShared(permits);
}

Semaphore 的主要方法都是在嵌套类 FairSync 和 NonFairSync 及其父类 Sync 中实现的,内部嵌套类也是 AQS 的典型用法。

华为OD机试:使用Ascend C语言实现Matmul与LeakyReLU融合算子的全流程设计与优化解析 通过本文的详细解析,相信你已经对华为OD机试中基于Ascend C语言的Matmul+LeakyReLU融合算子的设计与实现有了深入的理解。我们不仅从理论上探讨了融合算子的核心优势,还通过实际的代码示例演示了如何一步步完成算子的实现与优化。融合算子在AI算子开发中的应用,尤其是在处理大规模矩阵计算的场景中,能够显著提升计算效率,优化内存占用,并减少数据传输的开销。通过合理的Tiling策略设计,我们还能够充分利用多核处理器的算力,进一步提升AI模型的训练与推理性能。 阅读详情

相关推荐

如何设计一个低代码平台

近些年来,低代码发展火热,各种低代码平台如雨后春笋纷纷崛起,这些平台各定位不同,优劣不同,用户的选择空间很大。那么,如果用户想从零开始设计一个低代码平台,该如何做呢?

Jarod_Chou的博客 8256

Semaphore源码分析

公平锁,优先判断等待队列中是否有挂起的线程,如果有,则将当前线程添加到等待队列中,等待唤醒后抢夺信号量;非公平锁,不管等待队列中是否有挂起线程,优先尝试获取信号量,获取失败,将当前线程添加到等待队列。

输入知识,消化知识,输出知识,分享知识,教人让我学习更好,业精于勤荒于嬉,行成于思毁于随 445

开源光标主题实战:从Moshi Monsters到自定义指针的完整指南

光标主题是操作系统个性化的重要组成部分,它通过替换系统默认指针图标来改变视觉交互体验。其原理在于操作系统允许用户自定义指针资源文件,这些文件定义了不同状态下的光标图像。从技术价值看,一套设计良好的光标主题不仅能提升桌面美观度,还能增强用户的情感连接和操作愉悦感,是低成本高回报的数字幸福感提升方案。在应用场景上,无论是开发者、设计师还是普通用户,都可以通过更换光标主题来个性化工作环境。本文以热门的Moshi Monsters开源光标项目为例,深入解析了光标主题的设计逻辑、系统适配方案以及二次创作方法,涵盖了W

weixin_30879833的博客 552

源码分析_源码分析:Semaphore之信号量

简介Semaphore 又名计数信号量,从概念上来讲,信号量初始并维护一定数量的许可证,使用之前先要先获得一个许可,用完之后再释放一个许可。信号量通常用于限制线程的数量来控制访问某些资源,从而达到单机限流的目的,比如SpringCloud 中的Zuul 组件用的是 Hystrix 的信号量(semaphore)隔离模式。源码分析重要的内部类Semaphore 和 ReentrantLoc...

weixin_36210904的博客 93

抖音自定义卡片链接(图文链接)

抖音自定义可以自定义标题,打开链接,和展示图片 效果 主要代码 public void sendMessage(String conversationId, Object aBaseContent) throws Exception { // C233282u5.LIZIZ.LIZ().LIZIZ(LIZ).LIZ(obtain).LIZ(hLn).LIZ((AbstractC59811HHc) new H9Q()); Object HOa = ReflectionUtil

傅恒的博客 4140

STM32踩坑--NoST-LINK detected

这里出现的NoST-LINK detected是没有扫描到端口 在我使用一段Fly-MCU后,有一天突然发现出现如上错误,再检查的过程中检查以下几点 1.STM32 魔术棒的设置 1.1Debug设置 1.2 utilities 设置没有问题,与原来一样又看了下端口——在设备管理器中;也没有问题 ...

qq_53002477的博客 2万+

【并发编程】Semaphore 源码分析

应用场景、释放信号、获取许可、限流、实现原理等

yhl_jxy的博客 1549

BERTopic安装指南:hdbscan依赖问题全解析(附解决方案)

本文详细解析了安装BERTopic时常见的hdbscan依赖报错问题,深入剖析了C++编译环境缺失、Python版本兼容性以及包管理渠道混用三大核心原因。针对Windows、macOS和Linux不同系统,提供了创建虚拟环境、使用conda安装预编译包、安装C++编译工具等具体解决方案,帮助用户顺利安装BERTopic并开始文本主题建模实践。

weixin_29061041的博客 212

深入理解 Semaphore 【源码分析】

Semaphore 是信号量的意思,一般用来控制同时访问某个资源的线程数量,协调各个线程合理的访问公共资源,Semaphore 的底层依赖的是 AQS。Semaphore 使用计数器来控制对共享资源的访问, 如果计数器大于0,则表示允许访问共享资源, 如果为 0,则表示共享资源已经达到访问的上限就拒绝访问, 计数器的计数的就是允许同时访问共享资源的线程数。

weixin_42118323的博客 1417

五.EtherCAT开发之STM32F407ZGt6+ LAN9253 外置EEPROM配置数据含义

EtherCAT从站简称ESC,ESC在上电过程中,会自动加载EEPROM中前7个字(1word = 2 byte)到ESC寄存器。ESC寄存器总是可以被EtherCAT主站通过EtherCAT总线访问,无论PDI接口寄存器配置什么值。EEPROM存储器中的前7个字,将决定ESC的工作模式。

AIoT深度探索者 | 嵌入式系统架构师 深耕物联网(IoT)与人工智能(AI)融合技术,聚焦​​边缘计算、图像开发、低功耗通信协议​​,致力于智能硬件,关注我获取最新技术文章信息与海量资源~ 3465

从入门到精通:Cursor使用全攻略

Cursor是一款基于VSCode深度定制的AI编程工具,由Anysphere公司开发。它将AI技术与代码开发深度融合,能够理解自然语言指令并生成高质量代码,支持代码补全、跨文件上下文理解等功能。本文详细介绍了Cursor的安装设置、界面导航、基本操作和Composer模式等核心功能,并提供了高效提示词写作技巧和实际应用案例(如浏览器插件开发、复杂表单组件构建等)。文章还总结了使用注意事项和常见问题解决方案,展望了AI编程工具的发展前景。Cursor通过智能代码生成和项目理解能力,显著提升了开发效率,适合各

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 6456

AQS_Semaphore源码分析

Semaphore 顾名思义 就是信号量的意思,是基于AQS 的一个类Semaphore 维护了一个许可集合,在创建Semaphore的时候,设置上许可数,每条线程在只有在获得一个许可的时候才可以继续往下执行逻辑,申请多少许可,Semaphore的许可池中减少多少许可,当没有许可 或 许可不够的时候,申请许可的线程就会进入阻塞状态(加入阻塞队列)。Semaphore 信号量,通常用于控制同一时刻对共享资源的访问,也就是限流场景;Semaphore 的内部实现是就与AQS的共享锁来实现的;

一起加油!!! 287

BurpSuite工具HaE插件好用正则收集

数据集合面板里面直接查询捕获到的相关数据内容,省去一个个翻找数据包内容的烦恼。插件捕获到匹配正则表达式的数据包后,可以在。可以对正则条目进行添加、编辑、删除。规则信息管理,我们点击。

墨痕诉清风的博客 646

Java多线程 之 Semaphore源码分析

​目录 1、背景介绍 2、运行实例 3、源码分析 一、背景介绍 信号量(Semaphore),也被称为信号量,是在多线程环境下使用的一种工具类, 它负责协调各个线程, 以保证它们能够以一定数量地、正确、合理的使用公共资源。 每一个线程获取到一个计数信号量后,计数信号量就会减1,知道计数信号量为0,表示计数信号量已经不可用了,在许可可用前会阻塞每一个 acquire()。。拿到信号量的线程可以进入代码,否...

wenyixicodedog的博客 313

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

AQS 之 Semaphore 源码分析

信号量:用来限制能同时访问共享资源的线程上限。 和锁不一样,锁只有一个共享资源;信号量的共享资源有多个,对访问的线程上限做限制。作用: 可以做限流,只适合单机版,只限制线程数量,而不是限制资源数(tomcat 连接数) 可以作用于数据库连接池,享元模式下的,性能和可读性更好Semaphore semaphore = new Semaphore(n); 进入NonfairSync(permits) 方法 调用父类的 NonfairSync(permits) 方法 3:获取信号量 调用 acquire()方法

qq_40230026的博客 287

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

JUC-Semaphore源码分析

建议阅读Semaphore源码分析之前,先阅读,了解一下Semaphore用处以及基本用法。我们知道Semaphore是一个信号量,在java并发编程中,Semaphore本质上是一个共享锁的,用来限制多线程对共享资源的并发访问的。......

zqj1172102457的博客 423

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Semaphore 源码分析

Semaphore 源码分析 1. 在阅读源码时做了大量的注释,并且做了一些测试分析源码内的执行流程,由于博客篇幅有限,并且代码阅读起来没有 IDE 方便,所以在 github 上提供JDK1.8 的源码、详细的注释及测试用例。欢迎大家 star、fork ! 2. 由于个人水平有限,对源码的分析理解可能存在偏差或不透彻的地方还请大家在评论区指出,谢谢! 1. Semep...

昨夜凛雨 820

Java-juc(3) Semaphore 源码分析

文章目录Semaphore源码分析1.Semaphore介绍2.Semaphore的简单使用3.Semaphore源码分析3.1Sync源码3.2NonfairSync源码3.3FairSync源码3.4Semaphore的其他api的实现 Semaphore源码分析 本文源码基于JDK8。因为本人水平有限,错误和不足之处在所难免,欢迎指出错误和不足之处,一起进步。 阅读这篇文章最好对AQS有一定的了解。 1.Semaphore介绍 Semaphore是juc中的同步工具,使用Semaphore可以控制

qq_19007335的博客 359

Semaphore、CountDownLatch和CyclicBarrier原理及源码分析

前面《JUC并发核心AQS同步队列原理详解》介绍了AQS的同步等待队列的实现原理及源码分析,《ReentrantLock实现原理及源码分析》中介绍了AQS的同步队列独占模式实现的ReentranLock,这节将会介绍一下Semaphore、CountDownLatch和CyclicBarrier,并将会对源码进行分析。 一、Semaphore使用及源码分析 1、Semaphore的使用介绍 Semaphore也就是我们常说的信号量, Semaphore可以控制同时访问的线程个数,通过 acquire

没头脑遇到不高兴 817

源码分析:ReentrantLock、Semaphore以及CountDownLatch源码以及对应的设计模式

最近懵懵懂懂的看完了AQS的源码(源码分析:AQS源码),还是有很多不懂的地方,感觉还是要多来几遍的,为了更深入的理解AQS框架,看一下使用AQS的ReentrantLock、Semaphore以及CountDownLatch,直接上代码吧,解释都在注释里 /** * 这里是重入锁,我们需要关注一下重入锁是怎么实现的,两个条件: * 1. 在线程获取锁的时候,如果已经获取锁的线程是当前线程...

maoyeqiu的专栏 332

逐行源码分析AbstractQueuedSynchronizer(AQS)中Semaphore的源码实现

文章目录1 介绍2 场景3 使用4 分析 1 介绍 在上一篇博客:逐行源码分析AbstractQueuedSynchronizer(AQS)中ReentrantLock的源码实现 中是分析了关于高性能包java.util.concurrent 中的AQS得底层设计,以及ReentrantLock 的源码实现。 这篇博客,我们会分析AQS的另一个实现:信号量:Semaphore 2 场景 实际上对于Semaphore 这个类的使用,毫无客气的说,在平时的业务逻辑代码使用的很少(或许有些不知道咋使用的吧)。

zcswl7961的博客 2322

Java并发系列(6)Semaphore源码分析

Java并发系列(6)Semaphore源码分析

qq_41490913的博客 88

07-Semaphore及源码分析

Semaphore及源码分析 使用案例 semaphore也就是我们常说的信号灯,semaphore可以控制同时访问的线程个数,通过acquire获取一个许可,如果没有就等待,通过release释放一个许可。有点类似限流的作用。叫信号灯的原因也和他的用处有关,比如某商场就5个停车位,每个停车位只能停一辆车,如果这个时候来了10辆车,必须要等前面有空的车位才能进入。 使用场景 Semaphore比较...

weixin_39169791的博客 106
上一篇: 源码分析--CyclicBarrier
下一篇: 源码分析--ReentrantReadWriteLock(一)
CodersCoder
博客等级 码龄10年 90粉丝 258原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值