当前位置: 首页 > news >正文

SpringCloud 分布式锁Redisson锁的重入性与看门狗机制 高并发 可重入

可重入

Redisson 的锁支持 可重入性,这意味着同一个线程在获取锁后,如果再次尝试获取该锁,它可以成功地获得锁,而不会被阻塞。

  • 每次一个线程成功获取锁后,它的持有次数会增加。当线程再次获取该锁时,Redisson 会检查该线程是否已经持有锁。如果是,它会允许该线程再次获取锁,并将持有次数递增。
  • 每次释放锁时,持有次数会递减,直到持有次数变为零,锁才会被完全释放。

在这里插入图片描述

  public static void main(String[] args) {// 创建 Redisson 客户端配置Config config = new Config();config.useSingleServer().setAddress("redis://localhost:6379"); // 连接到本地 Redis 服务器RedissonClient redisson = Redisson.create(config);// 获取分布式锁RLock lock = redisson.getLock("accountLock");try {// 模拟账户操作的过程:先获取锁,进行第一次操作lock.lock();  //+1System.out.println("Lock acquired for the first time!");// 业务逻辑:扣款deductBalance(lock);} finally {// 释放锁:必须要释放与 lock.lock() 相同次数的 unlock() 才能完全释放锁lock.unlock();  //-1System.out.println("Lock released after first operation.");}}// 模拟业务逻辑:扣款操作private static void deductBalance(RLock lock) {// 业务逻辑需要在同一个线程中再次获取锁(模拟可重入性)lock.lock();//+1try {System.out.println("Lock acquired for the second time, performing deduct balance operation...");// 扣款逻辑,比如账户余额减少System.out.println("Balance deducted!");} finally {// 释放锁lock.unlock();//-1System.out.println("Lock released after deduct balance operation.");}}

当value值为0时就会释放锁。
在这里插入图片描述
这就是锁的可重入性。


看门狗机制

看门狗机制用于确保分布式系统中,锁或资源的持有者在预定时间内释放锁,否则看门狗会自动释放该锁,避免死锁等问题。帮助避免因某些异常(如程序崩溃或线程挂起)而导致锁被永久占用。

  • 自动续期:定期地自动刷新锁的过期时间。当锁被一个线程或进程持有时,会定期更新锁的 TTL(过期时间),以防止它被过期。即使持锁者在持有锁的过程中没有显式地释放锁,会确保锁不会在持有者不主动释放时过期,从而避免因过期造成的错误。

  • 自动解锁:如果持锁者超时或出现故障,会在检测到持锁者没有继续更新锁的超时时间后,自动释放锁,避免死锁。

  • 配置超时时间:可以与锁的过期时间和续期机制结合使用,可以通过配置来指定超时时间和自动续期的时间间隔。

在这里插入图片描述

相关源代码
尝试获取锁,如果不能获取锁,一直等待直到获取成功或者达到超时限制。中间部分涉及到锁的租期和超时处理,保证锁的可用性和避免死锁。interruptibly 参数提供了是否支持中断等待的选项。

private void lock(long leaseTime, TimeUnit unit, boolean interruptibly) throws InterruptedException {// 获取当前线程的ID,用于标识是哪一个线程请求锁long threadId = Thread.currentThread().getId();// 尝试获取锁,并获得锁的剩余有效时间 ttlLong ttl = this.tryAcquire(-1L, leaseTime, unit, threadId);// 如果成功获得锁(ttl != null),则进入锁处理逻辑if (ttl != null) {// 订阅当前线程的锁操作,返回一个 RFuture 对象,用于后续的异步操作RFuture<RedissonLockEntry> future = this.subscribe(threadId);// 根据 interruptibly 参数决定同步执行订阅操作if (interruptibly) {// 如果需要响应中断,使用带中断支持的同步方法this.commandExecutor.syncSubscriptionInterrupted(future);} else {// 如果不需要响应中断,直接使用同步方法this.commandExecutor.syncSubscription(future);}try {// 启动一个无限循环来持续尝试获取锁while (true) {// 每次进入循环时,重新尝试获取锁的剩余时间 ttlttl = this.tryAcquire(-1L, leaseTime, unit, threadId);// 如果 ttl 为 null,表示锁已经过期或无法获取,跳出循环if (ttl == null) {return;}// 如果 ttl >= 0L,表示可以继续持有锁if (ttl >= 0L) {try {// 尝试在 ttl 指定的时间内获取 latch((RedissonLockEntry) future.getNow()).getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS);} catch (InterruptedException var13) {// 如果在获取 latch 时发生 InterruptedException,则根据 interruptibly 变量决定是否抛出异常if (interruptibly) {// 如果需要响应中断,抛出 InterruptedExceptionthrow var13;}// 如果不需要响应中断,尝试继续获取 latch((RedissonLockEntry) future.getNow()).getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS);}} else if (interruptibly) {// 如果 ttl 为负值并且需要响应中断,调用 acquire 方法阻塞直到获取锁((RedissonLockEntry) future.getNow()).getLatch().acquire();} else {// 如果 ttl 为负值并且不需要响应中断,调用 acquireUninterruptibly 方法阻塞直到获取锁((RedissonLockEntry) future.getNow()).getLatch().acquireUninterruptibly();}}} finally {// 最终,取消订阅,释放资源this.unsubscribe(future, threadId);}}
}
  • 自动续期:通过 ttl 值和 latch.tryAcquire 方法,锁的超时时间会在持有锁的线程未释放锁的情况下自动延长,避免锁超时。
  • 避免死锁:如果线程因为异常等原因没有释放锁,看门狗机制会确保锁最终被释放。

文章转载自:

http://Ad6YkkQD.zdgqz.cn
http://vB78syEG.zdgqz.cn
http://We5LXL8p.zdgqz.cn
http://J4HpioML.zdgqz.cn
http://X61UpJcj.zdgqz.cn
http://qzowUDpr.zdgqz.cn
http://IK3jW8PA.zdgqz.cn
http://PH3Ayj8U.zdgqz.cn
http://c7GK4BKr.zdgqz.cn
http://1LRaezci.zdgqz.cn
http://f7yb2rpN.zdgqz.cn
http://1uEKmmJm.zdgqz.cn
http://AvSck0aK.zdgqz.cn
http://pZVKOd43.zdgqz.cn
http://YIKe2aRB.zdgqz.cn
http://P8qUlmDh.zdgqz.cn
http://kd3QHxGO.zdgqz.cn
http://7tEtoJXw.zdgqz.cn
http://cc8p77Fc.zdgqz.cn
http://psbKArhb.zdgqz.cn
http://Mk0VXE9A.zdgqz.cn
http://4JyCa7Ov.zdgqz.cn
http://77EN2WGl.zdgqz.cn
http://Jyj9zazP.zdgqz.cn
http://TnO8Cvdh.zdgqz.cn
http://Blq7BTZh.zdgqz.cn
http://MeEMGh6X.zdgqz.cn
http://K1z2dRAA.zdgqz.cn
http://Ftw7vsde.zdgqz.cn
http://BUmEZOG5.zdgqz.cn
http://www.dtcms.com/a/229421.html

相关文章:

  • Python语法基础篇(包含类型转换、拷贝、可变对象/不可变对象,函数,拆包,异常,模块,闭包,装饰器)
  • 深度学习入门——基于多层感知机的MNIST手写数字识别
  • Blinko智能笔记系统实现跨平台同步与隐私保护的完整技术方案解析
  • 【C/C++】template 入门到高阶简单大纲
  • 经典SQL查询问题的练习第四天
  • AutoCompose - 携程自动编排【开源】
  • 【亲测有效】Mybatis-Plus中更新字段为null
  • pytorch3d+pytorch1.10+MinkowskiEngine安装
  • PyTorch--池化层(4)
  • Attention Is All You Need (Transformer) 以及Transformer pytorch实现
  • pytorch基本运算-导数和f-string
  • 互联网大厂Java求职面试:AI大模型与云原生技术的深度融合
  • MySQL关系型数据库学习
  • 第三发 DSP 点击控制系统
  • 【MATLAB代码】制导方法介绍与例程——三点法|三维空间,动态目标导引(订阅专栏后可直接查看源代码)
  • leetcode hot100 链表(一)
  • matlab实现求解兰伯特问题
  • Axure形状类组件图标库(共8套)
  • xTimerChangePeriod无需先Stop
  • 我的世界模组开发——方块实体(1)
  • 部署过程中--常用Linux命令
  • centos中的ulimit命令
  • AD转嘉立创EDA
  • 手动删除网页上的禁止复制事件
  • C# Onnx 动漫人物头部检测
  • spacesniffer、WizTree等空间分析软件右键卡死?网盘惹的祸!
  • 学习路之PHP--easyswoole使用视图和模板
  • Spring Bean 为何“难产”?攻克构造器注入的依赖与歧义
  • Q:知识库-文档的搜索框逻辑是怎样的?
  • 【论文解读】ReAct:从思考脱离行动, 到行动反馈思考