分布式锁方案-Redisson

分布式锁:Redisson还实现了Redis文档中提到像分布式锁Lock这样的更高阶应用场景。事实上Redisson并没有不止步于此,在分布式锁的基础上还提供了联锁(MultiLock),读写锁(ReadWriteLock),公平锁(Fair Lock),红锁(RedLock),信号量(Semaphore),可过期性信号量(PermitExpirableSemaphore)和闭锁(CountDownLatch)这些实际当中对多线程高并发应用至关重要的基本部件。正是通过实现基于Redis的高阶应用方案,使Redisson成为构建分布式系统的重要工具。

依赖

<!-- https://mvnrepository.com/artifact/org.redisson/redisson -->
<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.15.5</version>
</dependency>

样例

	@AutowiredRedissonClient redissonClient;public String TestLock() {// 1.获取锁,只要锁的名字一样,获取到的锁就是同一把锁。RLock lock = redisson.getLock("redisson-lock");// 2.加锁lock.lock();try {System.out.println("加锁成功,执行后续代码。线程 ID:" + Thread.currentThread().getId());Thread.sleep(10000);} catch (Exception e) {//TODO} finally {lock.unlock();// 3.解锁System.out.println("Finally,释放锁成功。线程 ID:" + Thread.currentThread().getId());}return "test lock ok";}

锁无过期时间情况:服务停了,锁会释放-看门狗原理

如果负责储存这个分布式锁的 Redisson 节点宕机以后,而且这个锁正好处于锁住的状态时,这个锁会出现锁死的状态。为了避免这种情况的发生,Redisson内部提供了一个监控锁的看门狗,它的作用是在Redisson实例被关闭前,不断的延长锁的有效期。

默认情况下,看门狗的检查锁的超时时间是30秒钟,也可以通过修改Config.lockWatchdogTimeout来另行指定。

如果我们未制定 lock 的超时时间,就使用 30 秒作为看门狗的默认时间。只要占锁成功,就会启动一个定时任务:每隔 10 秒重新给锁设置过期的时间,过期时间为 30 秒。

设置锁过期时间

RLock lock = redissonClient.getLock("lock-expireTime");
lock.lock(10000, java.util.concurrent.TimeUnit.MILLISECONDS);

不使用此框架的情况下

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.data.redis.serializer.StringRedisSerializer;import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.TimeUnit;public class RedisTemplateDistributedLock {private RedisTemplate<String, Object> redisTemplate;public RedisTemplateDistributedLock(RedisTemplate<String, Object> redisTemplate) {this.redisTemplate = redisTemplate;// 设置序列化器,避免乱码问题redisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setValueSerializer(new StringRedisSerializer());}/*** 获取分布式锁* @param lockKey 锁的键* @param expireTime 锁的过期时间* @param timeUnit 时间单位* @return 锁的唯一标识,如果获取失败返回 null*/public String tryLock(String lockKey, long expireTime, TimeUnit timeUnit) {String requestId = UUID.randomUUID().toString();Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, expireTime, timeUnit);return result != null && result ? requestId : null;}/*** 释放分布式锁* @param lockKey 锁的键* @param requestId 锁的唯一标识* @return 是否成功释放锁*/public boolean releaseLock(String lockKey, String requestId) {String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";RedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);Long result = redisTemplate.execute(redisScript, Collections.singletonList(lockKey), requestId);return result != null && result == 1;}
}    
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;import java.util.concurrent.TimeUnit;public class RedisTemplateDistributedLockUsage {public static void main(String[] args) {// 假设这里已经有 RedisConnectionFactory 的实例RedisConnectionFactory redisConnectionFactory = null;RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(redisConnectionFactory);redisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setValueSerializer(new StringRedisSerializer());redisTemplate.afterPropertiesSet();RedisTemplateDistributedLock lock = new RedisTemplateDistributedLock(redisTemplate);String lockKey = "myDistributedLock";long expireTime = 10;TimeUnit timeUnit = TimeUnit.SECONDS;// 尝试获取锁String requestId = lock.tryLock(lockKey, expireTime, timeUnit);if (requestId != null) {try {System.out.println("成功获取到锁,开始执行临界区代码");// 模拟业务操作try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}} finally {// 释放锁boolean released = lock.releaseLock(lockKey, requestId);if (released) {System.out.println("锁已成功释放");} else {System.out.println("锁释放失败");}}} else {System.out.println("未能获取到锁");}}
}    

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

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

相关文章

【AI插件开发】Notepad++ AI插件开发实践:从Dock窗口集成到功能菜单实现

一、项目背景与技术选型 在上篇文章实现"选中即问AI"功能的基础上&#xff0c;本文重点解决AI对话窗口的集成与核心功能菜单的开发。通过Notepad插件体系&#xff0c;我们将实现以下功能矩阵&#xff1a; AI交互系统&#xff1a;支持自然语言提问与任务执行代码智能…

ControlNet-Tile详解

一、模型功能与应用 1. 模型功能 ControlNet-Tile模型的主要功能是图像的细节增强和质量提升。它通过以下几个步骤实现这一目标&#xff1a; 语义分割&#xff1a;模型首先对输入的图像进行语义分割&#xff0c;识别出图像中不同的区域和对象。这一步是为了让模型理解图像的内…

英飞凌高信噪比MEMS麦克风驱动人工智能交互

导言 在英飞凌&#xff0c;我们一直坚信卓越的音频解决方案对于提升消费类设备的用户体验至关重要。我们坚定不移地致力于创新&#xff0c;在主动降噪、语音透传、录音室录音、音频变焦和其他相关技术方面取得了显著进步&#xff0c;对此我们深感自豪。作为MEMS麦克风的领先供…

【Azure】如何使用 Docker CLI 和 Compose 将容器部署到 Azure ACI

推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战在云中运行容器可能既困难又令人困惑。有太多选项可供选择,而且还需要理解从虚拟网络到安全性的不同云服务的工作方式。更不用说编排器了。…

结构化剪枝(Structured Pruning)与动态蒸馏(Dynamic Distillation)

结构化剪枝&#xff08;Structured Pruning&#xff09;技术详解 核心原理 结构化剪枝通过模块级&#xff08;如层、通道、块&#xff09;而非单个权重的方式去除冗余参数&#xff0c;保留关键子网络。其优势在于&#xff1a; 硬件友好性&#xff1a;生成规则稀疏模式&#x…

linux shell 删除空行(remove empty lines)

命令行 grep -v ^$ file sed /^$/d file 或 sed -n /./p file awk /./ {print} file 或 awk {if($0!" ") print} tr -s "n"vim交互 %s/^n//g

数据库6(数据库指令)

之前所学的指令均为查找指令&#xff0c;即select相关语句 接下来的语句是增删改查的其他三部分&#xff0c;即增删改 1.删除 删除操作是三个操作中较为简单的&#xff0c;因为它只需要考虑数据的完整性 在实验时可以用表的复件来操作&#xff0c;防止操作不当导致数据库被…

web网页上实现录音功能(vue3)

文章目录 一. 前言二. 技术实现1.核心API介绍2.模板部分3.核心逻辑实现 4. 关键功能点解析 三. 完整代码四. 功能扩展建议 一. 前言 在Web开发中实现音频录制功能是许多应用场景的常见需求。本文将通过一个完整的Vue 3组件示例&#xff0c;详细解析如何利用现代浏览器API实现网…

安美数字酒店宽带运营系统存在SQL注入漏洞

免责声明&#xff1a;本号提供的网络安全信息仅供参考&#xff0c;不构成专业建议。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权&#xff0c;请及时与我联系&#xff0c;我将尽快处理并删除相关内容。 漏洞描述 安美数字酒店宽带运营系统的lang…

206. 反转链表 92. 反转链表 II 25. K 个一组翻转链表

leetcode Hot 100系列 文章目录 一、翻转链表二、反转链表 II三、K 个一组翻转链表总结 一、翻转链表 建立pre为空&#xff0c;建立cur为head&#xff0c;开始循环&#xff1a;先保存cur的next的值&#xff0c;再将cur的next置为pre&#xff0c;将pre前进到cur的位置&#xf…

【区块链安全 | 第十七篇】类型之引用类型(一)

文章目录 引用类型数据存储位置分配行为 数组特殊数组&#xff1a;bytes 和 string 类型bytes.concat 和 string.concat 的功能分配 memory 数组数组字面量&#xff08;Array Literals&#xff09;二维数组字面量数组成员&#xff08;Array Members&#xff09;悬空引用&#x…

selenium和pytessarct提取古诗文网的验证码(python爬虫)

代码实现的主要功能&#xff1a; 浏览器自动化控制 验证码图像获取与处理 OCR验证码识别 表单自动填写与提交 登录状态验证 异常处理与资源清理 1. 浏览器初始化与页面加载 driver webdriver.Chrome() driver.get("https://www.gushiwen.cn/user/login.aspx?fro…

【输入某年某日,判断这是这一年的第几天】

for语句和switch语句分别实现 文章目录 前言 一、用switch做 二、用for循环做 ​编辑 总结 前言 用两种不同的方法求解【输入某年某日&#xff0c;判断这是这一年的第几天】 一、用switch做 代码如下&#xff08;示例&#xff09;&#xff1a; int main() {int y, m, d, cou…

香港理工视觉语言模型赋能智能制造最新综述!基于视觉语言模型的人机协作在智能制造中的应用

作者&#xff1a;Junming FAN 1 ^{1} 1, Yue YIN 1 ^{1} 1, Tian WANG 1 ^{1} 1, Wenhang DONG 1 ^{1} 1, Pai ZHENG 1 ^{1} 1, Lihui WANG 2 ^{2} 2单位&#xff1a; 1 ^{1} 1香港理工大学工业及系统工程系&#xff0c; 2 ^{2} 2瑞典皇家理工学院论文标题&#xff1a; Vision-…

大智慧前端面试题及参考答案

如何实现水平垂直居中? 在前端开发中,实现元素的水平垂直居中是一个常见的需求,以下是几种常见的实现方式: 使用绝对定位和负边距:将元素的position设置为absolute,然后通过top、left属性将其定位到父元素的中心位置,再使用负的margin值来调整元素自身的偏移,使其水平垂…

算法基础_基础算法【高精度 + 前缀和 + 差分 + 双指针】

算法基础_基础算法【高精度 前缀和 差分 双指针】 ---------------高精度---------------791.高精度加法题目介绍方法一&#xff1a;代码片段解释片段一&#xff1a; 解题思路分析 792. 高精度减法题目介绍方法一&#xff1a;代码片段解释片段一&#xff1a; 解题思路分析 7…

OkHttpHttpClient

学习链接 okhttp github okhttp官方使用文档 SpringBoot 整合okHttp okhttp3用法 Java中常用的HTTP客户端库&#xff1a;OkHttp和HttpClient&#xff08;包含请求示例代码&#xff09; 深入浅出 OkHttp 源码解析及应用实践 httpcomponents-client github apache httpclie…

DoDAF科普

摘要 DoDAF&#xff08;Department of Defense Architecture Framework&#xff0c;美国国防部架构框架&#xff09;是一种专门为复杂系统设计的标准化框架&#xff0c;广泛应用于军事和国防项目。它通过提供一致的架构描述方法&#xff0c;确保跨组织、跨国界的系统集成和互操…

搭建qemu环境

1.安装qemu apt install qemu-system2.编译内核 设置gcc软链接sudo ln -s arm-linux-gnueabihf-gcc arm-linux-gccsudo ln -s arm-linux-gnueabihf-ld arm-linux-ldsudo ln -s arm-linux-gnueabihf-nm arm-linux-nmsudo ln -s arm-linux-gnueabihf-objcopy arm-linux-objc…

使用Claude Desktop和MCP工具创建个人编程助手

最近我在Claude Desktop上试用了MCP工具,体验过程令人兴奋不已。 我花时间测试了多个用于编程场景的MCP服务器——而Claude本就擅长编程,这一组合可谓相得益彰。 这些工具赋予Claude强大的自主任务执行能力,比如仅通过聊天就能实现Vibe编程。当然,必须谨慎控制其访问权限…