redis分布式锁(看门枸机制)

news/2024/9/21 8:02:16/

分布式锁确保在同一时间只有一个节点能获得对共享资源的独占访问权限,从而解决并发访问问题。

Redisson锁(简称看门狗)

它可以实现锁的延长,确保某个线程执行完才能让其他线程进行抢锁操作

引入看门狗机制后

如何使用?

1、引入依赖包

<!--Redisson依赖-->
<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.31.0</version>
</dependency>

2、配置类Config

@Configuration //标明是配置类
public class RedissonConfiguration {/*注入到IOC容器中*/@Beanpublic RedissonClient redissonClient(){//1.创建配置对象Config config = new Config();// 集群模式//config.useClusterServers().addNodeAddress("集群ip1", "集群id2");//2.根据config创建出RedissonClient实例config.useSingleServer().setAddress("redis://192.168.21.131:6379");
​//返回 RedissonClient实例return Redisson.create(config);}
}

3、编写Controller类

@RestController
@Slf4j
@RequestMapping("/api")
public class LockController {@Autowiredprivate RedissonClient redissonClient;
​@PutMapping("/watch-dog")public String redissonLock() {RLock lock = redissonClient.getLock("anyLock");try {//尝试获取锁,tryLock参数分别是:获取锁的最大等待时间(期间重试) ,锁自动释放时间,时间单位
​//锁的获取时间(重试获得锁)为5秒,超过时间线程未结束会延长锁的获取时间,其他线程无法获得锁//boolean isLocked = lock.tryLock(5,10, TimeUnit.SECONDS);//不指定锁超时时间,锁会无限续期,直到获得锁的业务逻辑失败boolean isLocked = lock.tryLock(5, TimeUnit.SECONDS);
​if (isLocked) {log.info("获取锁成功"+Thread.currentThread().getName()+":开始睡觉");Thread.sleep(5*1000);log.info("获取锁成功"+Thread.currentThread().getName()+":睡5秒,");
​// 业务逻辑Thread.sleep(10*1000);log.info("获取锁成功"+Thread.currentThread().getName()+":睡眠10秒,超过请求获取锁的时间");} else {log.info("锁未释放{}获取锁失败",Thread.currentThread().getName());return "无法获取锁";}
​} catch (InterruptedException e) {e.printStackTrace();return "线程被中断";} finally {if (lock.isHeldByCurrentThread()) {lock.unlock();}}
​return Thread.currentThread().getName();}
}
​
​

4、代码效果

避雷点

关于finallly释放锁时的踩雷点

直接lock.unlock会导致Redisson抛出异常,这个异常的原因是因为,当多个请求进来时,由于一个线程在占用着锁,其他线程无法获得锁,他就会走到finally中,去释放锁,但是由于它本身不带锁,就会触发异常。

解决办法

在释放之前添加if判断

finally{if(lock.isHeldByCurrenThread()){lock.unlock();  }
}
lock.isHeldByCurrenThread(),用于判断当前锁是否是当`前线程持有的,如果是就释放锁,不是就不让它释放,可以避免线程抛出异常。


http://www.ppmy.cn/news/1528317.html

相关文章

稳了,搭建Docker国内源图文教程

大家好&#xff0c;之前分享了我的开源作品 Cloudflare Workers Proxy&#xff0c;它的作用是代理被屏蔽的地址&#xff0c;理论上支持代理任何被屏蔽的域名&#xff0c;使用方式也很简单&#xff0c;只需要设置环境变量 PROXY_HOSTNAME 为被屏蔽的域名&#xff0c;最后通过你的…

如何确保Java程序分发后不被篡改?使用JNI对Java程序进行安全校验

前言 众所周知&#xff0c;Java/Kotlin编译后会编译成smali&#xff0c;使用Jadx这类的反编译工具或者Hook工具就能很轻松的把我们的软件安全校验给破解了。 为了防止这种情况发生&#xff0c;我们一般会将核心代码使用C编写&#xff0c;然后使用JNI技术&#xff0c;使用Java…

C#基于SkiaSharp实现印章管理(8)

上一章虽然增加了按路径绘制文本&#xff0c;支持按矩形、圆形、椭圆等路径&#xff0c;但测试时发现通过调整尺寸、偏移量等方式不是很好控制文本的位置。相对而言&#xff0c;使用弧线路径&#xff0c;通过弧线起始角度及弧线角度控制文本位置更简单。同时基于路径绘制文本时…

linux命令行快捷键

第一章 linux之帮助命令 第二章 linux命令行快捷键 文章目录 linux命令行快捷键 linux命令行快捷键 Tab 命令补全或文件补全Ctrlu 删除或剪切光标之前的命令Ctrla 将光标移动到命令行开头Ctrle 将光标移动到命令行结尾ctrlc 终止当前命令ctrll 清屏ctrly 粘贴ctrlu的内容 参考…

2024年“华为杯”研赛第二十一届中国研究生数学建模竞赛解题思路|完整代码论文集合

我是Tina表姐&#xff0c;毕业于中国人民大学&#xff0c;对数学建模的热爱让我在这一领域深耕多年。我的建模思路已经帮助了百余位学习者和参赛者在数学建模的道路上取得了显著的进步和成就。现在&#xff0c;我将这份宝贵的经验和知识凝练成一份全面的解题思路与代码论文集合…

CDA Level 1 业务数据分析

目录 理解业务数据分析方法、掌握业务数据分析流程、能够使用及设计创建业务指标、能够结合业务模型及业务分析方法正确理解业务问题&#xff0c;找到问题原因&#xff0c;并能够提出解决问题建议&#xff0c;这个章节的应用会考的比较多&#xff08;终于正经起来了呢&#xf…

预测合理交易目标:中断形态趋势分析

日常交易时&#xff0c;我们除了通过判断一些重要指标来预测趋势走向之外&#xff0c;观察趋势的形态变化也是我们技术分析中很重要的分析方式。而识别并理解这些形态可以为交易者提供进出场的关键信号。今天我们就来说说其中一种形态——中断形态&#xff01; 中继形态在市场…

Eclipse如何调整编辑器中的字体大小?

在 Eclipse 中&#xff0c;可以通过以下步骤调整编辑器中代码的字体大小&#xff08;size&#xff09;&#xff1a; 调整字体大小步骤&#xff1a; 打开首选项&#xff08;Preferences&#xff09;&#xff1a; 在菜单栏中&#xff0c;选择 Window&#xff08;对于 Windows/Li…