Redisson 锁续期举个实际例子,我看看代码样子

19次阅读
没有评论

好的,我来给你展示一个 Redisson 分布式锁续期的实际代码例子:

  1. import org.redisson.Redisson;
  2. import org.redisson.api.RLock;
  3. import org.redisson.api.RedissonClient;
  4. import org.redisson.config.Config;
  5. import java.util.concurrent.TimeUnit;
  6. public class RedissonLockExample {
  7. private static RedissonClient redissonClient;
  8. static {
  9. // 初始化 Redisson 客户端
  10. Config config = new Config();
  11. config.useSingleServer()
  12. .setAddress("redis://127.0.0.1:6379");
  13. redissonClient = Redisson.create(config);
  14. }
  15. public static void main(String[] args) {
  16. // 获取锁实例
  17. RLock lock = redissonClient.getLock("my_distributed_lock");
  18. try {
  19. // 方式1: 普通加锁,自动续期(默认锁超时30秒,每10秒续期一次)
  20. lock.lock();
  21. // 方式2: 指定锁超时时间(不会自动续期,超时后自动释放)
  22. // lock.lock(10, TimeUnit.SECONDS);
  23. // 方式3: 尝试获取锁,最多等待5秒,获取后持有10秒(不会自动续期)
  24. // boolean locked = lock.tryLock(5, 10, TimeUnit.SECONDS);
  25. // if (!locked) {
  26. // System.out.println("获取锁失败");
  27. // return;
  28. // }
  29. System.out.println("成功获取锁,开始执行业务逻辑...");
  30. // 模拟长时间业务操作(超过锁超时时间,验证续期效果)
  31. // 这里休眠25秒,超过默认的30秒锁超时的三分之二
  32. Thread.sleep(25000);
  33. System.out.println("业务逻辑执行完成,准备释放锁");
  34. } catch (InterruptedException e) {
  35. Thread.currentThread().interrupt();
  36. } finally {
  37. // 释放锁
  38. if (lock.isLocked() && lock.isHeldByCurrentThread()) {
  39. lock.unlock();
  40. System.out.println("锁已释放");
  41. }
  42. }
  43. // 关闭客户端
  44. redissonClient.shutdown();
  45. }
  46. }

关键点说明:

  1. 自动续期机制
    • 使用 lock() 不加参数时,默认锁超时时间为 30秒
    • Redisson 会启动一个后台定时任务,每 10秒 检查一次锁是否仍被持有
    • 如果持有,则自动将锁的过期时间延长至 30秒
  2. 续期原理
    1. // Redisson 内部续期逻辑(简化版)
    2. // 每隔 lockWatchdogTimeout / 3 = 10秒 执行一次续期
    3. public void renewExpiration() {
    4. ExpirationEntry entry = EXPIRATION_RENEWAL_MAP.get(getEntryName());
    5. if (entry == null) {
    6. return;
    7. }
    8. // 通过 Lua 脚本原子性地续期
    9. schedule(executorService, () -> {
    10. if (entry.isCancelled()) {
    11. return;
    12. }
    13. // 延长锁过期时间
    14. Long ttl = commandExecutor.evalWriteAsync(getName(),
    15. LongCodec.INSTANCE, RedisCommands.EVAL_LONG,
    16. "if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " +
    17. "redis.call('pexpire', KEYS[1], ARGV[1]); return 1; " +
    18. "end; return 0;",
    19. Collections.singletonList(getName()),
    20. internalLockLeaseTime, getLockName());
    21. // 继续调度下次续期
    22. renewExpiration();
    23. }, internalLockLeaseTime / 3, TimeUnit.MILLISECONDS);
    24. }
  3. 手动指定超时时间
    • lock(10, TimeUnit.SECONDS) – 锁超时10秒,不会自动续期
    • tryLock(waitTime, leaseTime, TimeUnit) – 最多等待waitTime秒,获取后持有leaseTime秒
  4. 锁的释放
    • 业务完成后调用 unlock() 释放
    • 使用 isLocked() 和 isHeldByCurrentThread() 确保安全释放

Maven 依赖:

  1. <dependency>
  2. <groupId>org.redisson</groupId>
  3. <artifactId>redisson</artifactId>
  4. <version>3.23.5</version>
  5. </dependency>

场景适用:

  • 需要执行较长时间的业务操作(如批量数据处理)
  • 防止因业务执行时间超过锁超时导致的并发问题
  • 需要高可靠的分布式锁保证
正文完
 0
bdspAdmin
版权声明:本站原创文章,由 bdspAdmin 于2026-05-07发表,共计2219字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)