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

RedissonLock-tryLock-续期

redisson版本3.16.6

1.什么是看门狗

Redisson提供的分布式锁是支持锁自动续期的,也就是说,如果线程仍旧没有执行完,那么redisson会自动给redis中的目标key延长超时时间,这在Redisson中称之为 Watch Dog 机制。默认情况下,看门狗的检查锁的超时时间是30秒钟,也可以通过修改Config.lockWatchdogTimeout来另行指定。

2.什么情况会续期

什么情况会续期,总结一句话:不传入leaseTime(锁自动释放时间),使用默认值-1

tryLock可传入参数有三个

lockName需要锁住的内容关键字

waitTime 获取锁最大等待时间,没有传-1

leaseTime锁自动释放时间,没有传-1

boolean tryLock 重载了三个方法,分别如下:

boolean tryLock(String lockName);boolean tryLock(String lockName, long waitTime) throws InterruptedException;boolean tryLock(String lockName, long waitTime, long leaseTime) throws InterruptedException;

从实现上看,使用才传参,不用,千万别主动写入-1,会对入参有校验。可以实现续期的情况只能使用前两个构造器,不能使用主动传入leaseTime的构造器。为什么这么说呢,源码如下:

方法都会调用tryLock获取锁,tryLock方法中调用tryAcquire方法

public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {long time = unit.toMillis(waitTime);long current = System.currentTimeMillis();long threadId = Thread.currentThread().getId();Long ttl = tryAcquire(waitTime, leaseTime, unit, threadId);// lock acquiredif (ttl == null) {return true;}....省略

tryAcquire方法会调用tryAcquireAsync,源码如下:

private <T> RFuture<Long> tryAcquireAsync(long waitTime, long leaseTime, TimeUnit unit, long threadId) {RFuture<Long> ttlRemainingFuture;if (leaseTime != -1) {ttlRemainingFuture = tryLockInnerAsync(waitTime, leaseTime, unit, threadId, RedisCommands.EVAL_LONG);} else {ttlRemainingFuture = tryLockInnerAsync(waitTime, internalLockLeaseTime,TimeUnit.MILLISECONDS, threadId, RedisCommands.EVAL_LONG);}ttlRemainingFuture.onComplete((ttlRemaining, e) -> {if (e != null) {return;}// lock acquiredif (ttlRemaining == null) {if (leaseTime != -1) {internalLockLeaseTime = unit.toMillis(leaseTime);} else {scheduleExpirationRenewal(threadId);}}});return ttlRemainingFuture;
}

从源码上看,只有当leaseTime为-1时scheduleExpirationRenewal这个方法才会生效,这个方法会进行续期。

3.续期源码分析

启一个task任务进行锁的自动续期

scheduleExpirationRenewal()->renewExpiration()

private void renewExpiration() {ExpirationEntry ee = EXPIRATION_RENEWAL_MAP.get(getEntryName());if (ee == null) {return;}// 启一个定时任务Timeout task = commandExecutor.getConnectionManager().newTimeout(new TimerTask() {@Overridepublic void run(Timeout timeout) throws Exception {ExpirationEntry ent = EXPIRATION_RENEWAL_MAP.get(getEntryName());if (ent == null) {return;}Long threadId = ent.getFirstThreadId();if (threadId == null) {return;}// 核心续期代码,执行lua脚本RFuture<Boolean> future = renewExpirationAsync(threadId);future.onComplete((res, e) -> {if (e != null) {log.error("Can't update lock " + getRawName() + " expiration", e);EXPIRATION_RENEWAL_MAP.remove(getEntryName());return;}if (res) {// renewExpirationAsync执行成功,进行递归调用,调用自己,就可以实现不停的续期// 第一次执行这个函数,设置task任务,10s后执行task任务,刷新有效期,又重新设置一个task任务,10s后执行renewExpiration();} else {cancelExpirationRenewal(null);}});}// 定时任务是lockWatchdogTimeout的1/3时间去执行,就是每10s执行一次,renewExpirationAsync进行续期}, internalLockLeaseTime / 3, TimeUnit.MILLISECONDS);ee.setTimeout(task);
}

http://www.lryc.cn/news/328006.html

相关文章:

  • MSTP环路避免实验(华为)
  • IoT网关在智能制造工厂生产线监控与管理中的应用-天拓四方
  • niushop单商户V5多店版源码分享三端uniapp打包方法包括PC端_小程序或h5端打包_收银端打包_APP端打包_商户端
  • npm包发布
  • C#使用SQLite(含加密)保姆级教程
  • C# 异步与 Unity 协程(实例讲解)
  • iOS - Runloop介绍
  • 探究分布式事务:深入ACID特性在分布式系统中的挑战与解决方案
  • PCI总线管脚定义(引脚定义)
  • 万字详解PHP+Sphinx中文亿级数据全文检索实战(实测亿级数据0.1秒搜索耗时)
  • 数据库索引及优化
  • flink: 将接收到的tcp文本流写入HBase
  • SpringBoot集成knife4j
  • Vue3之setup方法
  • MySQL常见索引及其创建
  • 高效测量“芯”搭档 | ACM32激光测距仪应用方案
  • 基于Hive大数据分析springboot为后端以及vue为前端的的民宿系
  • pnpm、monorepo分包管理、多包管理、npm、vite、前端工程化、保姆级教程
  • vue3封装Element分页
  • 真机 ARM64 架构转模拟器 ARM64 架构
  • 敏捷教练CSM认证考了有没有用,谁说了算?
  • Docker-Container
  • 下载安装anaconda和pytorch的详细方法,以及遇到的问题和解决办法
  • 2020年天津市二级分类土地利用数据(矢量)
  • 设计模式——结构型——外观模式Facade
  • OpenGL的MVP矩阵理解
  • 前端超分辨率技术应用:图像质量提升与场景实践探索-设计篇
  • C++11入门手册第一节,学完直接上手Qt(共两节)
  • Docker部署MinIO对象存储服务
  • 基于Echarts的超市销售可视化分析系统(数据+程序+论文)