好的,我来给你展示一个 Redisson 分布式锁续期的实际代码例子:
import org.redisson.Redisson;import org.redisson.api.RLock;import org.redisson.api.RedissonClient;import org.redisson.config.Config;import java.util.concurrent.TimeUnit;public class RedissonLockExample {private static RedissonClient redissonClient;static {// 初始化 Redisson 客户端Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379");redissonClient = Redisson.create(config);}public static void main(String[] args) {// 获取锁实例RLock lock = redissonClient.getLock("my_distributed_lock");try {// 方式1: 普通加锁,自动续期(默认锁超时30秒,每10秒续期一次)lock.lock();// 方式2: 指定锁超时时间(不会自动续期,超时后自动释放)// lock.lock(10, TimeUnit.SECONDS);// 方式3: 尝试获取锁,最多等待5秒,获取后持有10秒(不会自动续期)// boolean locked = lock.tryLock(5, 10, TimeUnit.SECONDS);// if (!locked) {// System.out.println("获取锁失败");// return;// }System.out.println("成功获取锁,开始执行业务逻辑...");// 模拟长时间业务操作(超过锁超时时间,验证续期效果)// 这里休眠25秒,超过默认的30秒锁超时的三分之二Thread.sleep(25000);System.out.println("业务逻辑执行完成,准备释放锁");} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {// 释放锁if (lock.isLocked() && lock.isHeldByCurrentThread()) {lock.unlock();System.out.println("锁已释放");}}// 关闭客户端redissonClient.shutdown();}}
关键点说明:
- 自动续期机制:
- 使用
lock()不加参数时,默认锁超时时间为 30秒 - Redisson 会启动一个后台定时任务,每 10秒 检查一次锁是否仍被持有
- 如果持有,则自动将锁的过期时间延长至 30秒
- 使用
- 续期原理:
// Redisson 内部续期逻辑(简化版)// 每隔 lockWatchdogTimeout / 3 = 10秒 执行一次续期public void renewExpiration() {ExpirationEntry entry = EXPIRATION_RENEWAL_MAP.get(getEntryName());if (entry == null) {return;}// 通过 Lua 脚本原子性地续期schedule(executorService, () -> {if (entry.isCancelled()) {return;}// 延长锁过期时间Long ttl = commandExecutor.evalWriteAsync(getName(),LongCodec.INSTANCE, RedisCommands.EVAL_LONG,"if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " +"redis.call('pexpire', KEYS[1], ARGV[1]); return 1; " +"end; return 0;",Collections.singletonList(getName()),internalLockLeaseTime, getLockName());// 继续调度下次续期renewExpiration();}, internalLockLeaseTime / 3, TimeUnit.MILLISECONDS);}
- 手动指定超时时间:
lock(10, TimeUnit.SECONDS)– 锁超时10秒,不会自动续期tryLock(waitTime, leaseTime, TimeUnit)– 最多等待waitTime秒,获取后持有leaseTime秒
- 锁的释放:
- 业务完成后调用
unlock()释放 - 使用
isLocked()和isHeldByCurrentThread()确保安全释放
- 业务完成后调用
Maven 依赖:
<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.23.5</version></dependency>
场景适用:
- 需要执行较长时间的业务操作(如批量数据处理)
- 防止因业务执行时间超过锁超时导致的并发问题
- 需要高可靠的分布式锁保证
正文完