从Redisson的RedissonSemaphore引发的信号量实际含义的思考

news2024/11/25 2:45:57

Semaphore到底该如何使用

事情的起因是最近在看redisson的源码,刚好看到了RedissonSemaphore的acquire/release实现。

public RFuture<Void> releaseAsync(int permits) {
        if (permits < 0) {
            throw new IllegalArgumentException("Permits amount can't be negative");
        }
        if (permits == 0) {
            return new CompletableFutureWrapper<>((Void) null);
        }

        RFuture<Void> future = commandExecutor.syncedEval(getRawName(), StringCodec.INSTANCE, RedisCommands.EVAL_VOID,
                "local value = redis.call('incrby', KEYS[1], ARGV[1]); " +
                        "redis.call('publish', KEYS[2], value); ",
                Arrays.asList(getRawName(), getChannelName()), permits);
        if (log.isDebugEnabled()) {
            future.thenAccept(o -> {
                log.debug("released, permits: {}, name: {}", permits, getName());
            });
        }
        return future;
    }

这段代码并没有去校验key是否存在,以及设置的semaphore的最大值是多少,直接进行了incr操作。
如果其他客户端存在重复release()的行为,就会导致凭证超发的情况发生。

因此回过头去看了一下jdk的semaphore的实现。

Semaphore semaphore = new Semaphore(1);
        semaphore.acquire();
        semaphore.release();
        semaphore.release();
        semaphore.release();
        semaphore.release();
        boolean b1 = semaphore.tryAcquire();
        boolean b2 = semaphore.tryAcquire();
        boolean b3 = semaphore.tryAcquire();

        System.out.println(b1 + ":" + b2 + ":" + b3);

这段代码的执行结果是:true:true:true

JDK的semaphore的release()核心代码如下:

 protected final boolean tryReleaseShared(int releases) {
            for (;;) {
                int current = getState();
                int next = current + releases;
                if (next < current) // overflow
                    throw new Error("Maximum permit count exceeded");
                if (compareAndSetState(current, next))
                    return true;
            }
        }

这里只是在release的时候,将当前current和next的值做比对,防止并发情况下修改值异常问题,并不会去校验new Semaphore()时传入的初始化值。其中getState()返回的就是初始化时的state。

    protected final int getState() {
        return state;
    }

在tryReleaseShared()方法的compareAndSetState(current, next)中,会修改这个state的值。
在这里插入图片描述
在这里插入图片描述
所以在JDK的semaphore实现中,new Semaphore(int permits)传入的值,只是一个初始化的值,如果在实际使用的时候,进行了重复release()释放,就会导致多余的凭证超发的问题。

在了解了JDK的semaphore的实际实现后,就不难理解redisson的RedissonSemaphore实现了,是完全与JDK保持一致的。

在JDK的semaphore使用时,需要保证多线程进行凭证释放的时候,不会重复release(),防止凭证超发,而使用RedissonSemaphore的时候,一般是分布式的场景,所以常见的凭证超发的情况可能就在于重复消费,所以需要调用方自己保证调用幂等,避免凭证超发。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/571444.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微信小程序 基础模板引入sass的两种方法

推荐使用第二种方法 一、VSCode扩展引入&#xff08;旧&#xff09; 1.vscode搜索扩展 Easy Sass安装 2.微信开发者工具导入vscode安装的所有扩展 3.修改sass扩展配置 打开扩展目录 找到刚导入的sass扩展 打开package.json文件 改成这样 保存 4.重新打开此项目 配置完事 5.使…

torch.distributed.launch多卡多机

torch.distributed.launch命令介绍 我们在训练分布式时候&#xff0c;会使用到 torch.distributed.launch 可以通过命令&#xff0c;来打印该模块提供的可选参数 python -m torch.distributed.launch --help usage: launch.py [-h] [--nnodes NNODES] [--node_rank NODE_RANK]…

Flutter_环境配置

FlutterSDK 下载FlutterSDK管理工具<SideKick>下载安装<SideKick>下载FlutterSDK设置全局SDK 修改Flutter配置文件获取全局SDK路径 验证配置是否成功验证环境配置 下载FlutterSDK管理工具 下载安装 SideKick下载链接 下载FlutterSDK 打开 SideKick选择需要的SD…

基于Python/MATLAB长时间序列遥感数据处理及在全球变化、物候提取、植被变绿与固碳分析、生物量估算与趋势分析

目录 专题一、长时序遥感产品在全球变化/植被变绿/植被物候等方面的应用 专题二、MODIS遥感数据产品预处理 专题三、长时序MODIS遥感数据产品时间序列重构 专题四、基于GIMMS 3g和MODIS NDVI构建更长时序遥感数据 专题五、植被物候提取与分析实践应用 专题六、植被变绿趋…

卷S人的166页精品Java面试手册,17大java面试系列专题让你全方位暴击大厂Java面试官!

你有面试机会了吗&#xff1f; 近期&#xff0c;肯定有很多小伙伴&#xff0c;投出去的简历HR基本上都是已读不回&#xff0c;甚至都没有任何回复&#xff0c;或者平台默认筛选&#xff0c;你的简历HR根本就看不到。 即使有些小伙伴简历通过&#xff0c;收到面试邀请了&#…

RestCloud荣膺广东省优秀软件产品奖,引领国内数据集成领域!

近日&#xff0c;“2022年广东软件风云榜”名单公布&#xff0c;“谷云ETL数据交换软件”凭借其在助力企业数字化转型升级过程中的卓越表现&#xff0c;荣获由羊城晚报报业集团、广东软件行业协会、广东省大数据协会联合颁发的“优秀软件产品和解决方案”奖。 数字化转型是推动…

【CCF- CSP 202104-2 邻域均值 二维数组前缀和满分题解】

代码思路&#xff1a; 本题如果直接用暴力求解的话只能得70分。 运用到了二维数组的前缀和&#xff0c;难点是如何求出二维数组的前缀和并计算出领域所有元素的和。 注意计算平均数的时候要保证精度相同&#xff0c;所有都要化为double型&#xff0c;否则会出错。 首先&…

探索商机,连接世界——第133届广交会买家信息帮你快速找到合适的客户

亲爱的商家和供应商们&#xff01;&#xff01; 您是否在寻找拓展市场和国际贸易的机会&#xff1f;你想找到合适的客户&#xff0c;推广你的产品和服务&#xff0c;取得更大的商业成功吗&#xff1f;那么&#xff0c;我们给你带来了一个难得的机会&#xff01; 随着第133届广…

【开源项目】Dynamic-Tp告警系统的源码解析

序言 【开源项目】Dynamic-Tp核心流程源码解读&#xff0c;继上回解读完DynamicTp这个开源项目的源码&#xff0c;觉得其中的告警机制也是十分精彩&#xff0c;如果能学会&#xff0c;用在自己的项目中&#xff0c;那才能说得上掌握了DynamicTp这个开源项目的源码理解的精髓。…

零碳光储 数能未来 | 全系光储产品实力吸睛,科士达精彩亮相SNEC 2023

5月24日&#xff0c;光伏行业最具影响力的全球性展会——“SNEC 2023”在上海盛大开幕。作为行业领先的全能方案供应商&#xff0c;科士达以“零碳光储 数能未来”为主题&#xff0c;携全系光储产品及解决方案重磅亮相。 展会现场&#xff0c;科士达展出的全系解决方案涵盖分布…

APACHE-ATLAS-2.1.0简介(三)

APACHE-ATLAS-2.1.0简介(一) APACHE-ATLAS-2.1.0简介(二) 写在前面 ATLAS为组织提供开放式的元数据管理和治理功能&#xff0c;用以构建其数据资产目录&#xff0c;对这些资产进行分类和管理&#xff0c;形成数据字典。 名词解释 元数据&#xff1a;就是用于描述数据的数据…

js实现PDF 预览和文件下载

在开发过程中要求对 PDF 类型的发票提供 预览 和 下载 功能&#xff0c;PDF 类型文件的来源又包括 H5 移动端 和 PC 端&#xff0c;而针对这两个不同端的处理会有些许不同&#xff0c;下文会有所提及。 针对 PDF 预览 的文章不在少数&#xff0c;但似乎都没有提及可能遇到的问…

【Java-Crawler】SpringBoot集成WebMagic实现爬虫出现的问题集(一)

SpringBoot集成WebMagic实现爬虫出现的问题集&#xff08;一&#xff09; 一、SpringBoot集成WebMagic框架日志异常问题及解决方案二、使用 Firefox 驱动&#xff08;geckodriver&#xff09;三、设置WebMagic中site中的User-Agent&#xff08;避免反爬虫&#xff09; 一、Spri…

【网络编程】demo版TCP网络服务器实现

文章目录 一、引入二、服务端实现2.1 创建套接字socket2.2 绑定bind2.3 设置监听状态listen2.4 获取新链接accept2.5 获取信息与返回信息&#xff08;文件操作&#xff09; 三、客户端实现3.1 创建套接字socket3.2 绑定问题3.3 发起链接connect3.4 客户端并行3.4.1 多进程版3.4…

公网远程访问本地Jupyter Notebook服务

文章目录 前言视频教程1. Python环境安装2. Jupyter 安装3. 启动Jupyter Notebook4. 远程访问4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5. 固定公网地址 转载自cpolar的文章&#xff1a;公网远程访问Jupyter Notebook【Cpolar内网穿透】 前言 Jupyter Notebook&am…

针对UDP协议的攻击与防御

一、UDP协议概述 UDP&#xff08;User Datagram Protocol&#xff0c;用户数据报协议&#xff09;是TCP/IP协议栈中的一种无连接的传输协议&#xff0c;能够提供面向事务的简单不可靠数据传输服务。 1&#xff0e;UDP的报文格式 UDP的报文格式如图1所示。 图1 UDP报文格式 …

怎么在pdf文件上添加水印

怎么在pdf文件上添加水印&#xff1f;PDF添加水印是一种十分实用的方式&#xff0c;可以大大提高PDF文档的安全性和防护能力。在实际操作中&#xff0c;我们可以根据具体需求在PDF文件的各个页面上添加水印。这样即使你的PDF文件被他人恶意盗用&#xff0c;也可以快速、准确地找…

堤防安全自动化监测系统

项目背景 我国河系众多&#xff0c;海岸线漫长&#xff0c;在江边、海边修筑修筑着几万公里的提防设施保卫着沿江、沿海居民的生命安全&#xff0c;也保卫着经济发展的累累硕果。近年来&#xff0c;政府加大了堤防建设改造力度&#xff0c;提高了部分堤段的防洪能力。同时&…

统信UOS系统开发笔记(一):国产统信UOS系统搭建开发环境之虚拟机安装

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/130876940 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软…

vue 弹窗实现方法

Vue实现弹窗的方法有很多种&#xff0c;这里给出一个简单的示例&#xff1a; 1. 首先&#xff0c;在Vue项目中创建一个名为Modal.vue的组件文件&#xff1a; html <template> <div class"modal-mask" v-show"visible" click.self"close"…