RedissonLockUtil.java 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package com.txz.mall.util;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.redisson.api.RLock;
  4. import org.redisson.api.RedissonClient;
  5. import org.springframework.stereotype.Component;
  6. import javax.annotation.PostConstruct;
  7. import javax.annotation.Resource;
  8. import java.util.concurrent.TimeUnit;
  9. @Slf4j
  10. @Component
  11. public class RedissonLockUtil {
  12. @Resource
  13. private RedissonClient redissonClient;
  14. private static RedissonLockUtil instance;
  15. private RedissonLockUtil() {}
  16. @PostConstruct
  17. public void init() {
  18. instance = this;
  19. }
  20. /**
  21. * 获取分布式锁(阻塞式,直到获取锁为止)
  22. * @param lockKey 锁的唯一标识
  23. * @return 锁对象
  24. */
  25. public static RLock getLock(String lockKey) {
  26. RLock lock = instance.redissonClient.getLock(lockKey);
  27. try {
  28. // 尝试获取锁,一直阻塞直到获取成功
  29. lock.lock();
  30. log.info("获取锁成功,lockKey: {}", lockKey);
  31. } catch (Exception e) {
  32. log.error("获取锁失败,lockKey: {}, 异常: {}", lockKey, e.getMessage());
  33. throw new RuntimeException("获取分布式锁失败", e);
  34. }
  35. return lock;
  36. }
  37. /**
  38. * 获取分布式锁(带超时,超过时间未获取则放弃)
  39. * @param lockKey 锁的唯一标识
  40. * @param waitTime 等待获取锁的最大时间(单位:秒)
  41. * @param leaseTime 锁的自动释放时间(单位:秒)
  42. * @return 是否获取到锁
  43. */
  44. public static boolean tryLock(String lockKey, int waitTime, int leaseTime) {
  45. RLock lock = instance.redissonClient.getLock(lockKey);
  46. try {
  47. // 尝试在 waitTime 秒内获取锁,若获取成功则保持 leaseTime 秒后自动释放
  48. boolean isLocked = lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
  49. if (isLocked) {
  50. log.info("尝试获取锁成功,lockKey: {}", lockKey);
  51. } else {
  52. log.warn("尝试获取锁失败,lockKey: {}", lockKey);
  53. }
  54. return isLocked;
  55. } catch (InterruptedException e) {
  56. log.error("尝试获取锁被中断,lockKey: {}, 异常: {}", lockKey, e.getMessage());
  57. Thread.currentThread().interrupt();
  58. return false;
  59. } catch (Exception e) {
  60. log.error("尝试获取锁异常,lockKey: {}, 异常: {}", lockKey, e.getMessage());
  61. return false;
  62. }
  63. }
  64. /**
  65. * 释放分布式锁
  66. * @param lockKey 锁的唯一标识
  67. */
  68. public static void unlock(String lockKey) {
  69. RLock lock = instance.redissonClient.getLock(lockKey);
  70. try {
  71. if (lock.isLocked() && lock.isHeldByCurrentThread()) {
  72. lock.unlock();
  73. log.info("释放锁成功,lockKey: {}", lockKey);
  74. } else {
  75. log.warn("释放锁失败,锁未被当前线程持有或已释放,lockKey: {}", lockKey);
  76. }
  77. } catch (Exception e) {
  78. log.error("释放锁异常,lockKey: {}, 异常: {}", lockKey, e.getMessage());
  79. throw new RuntimeException("释放分布式锁失败", e);
  80. }
  81. }
  82. /**
  83. * 释放分布式锁(带锁对象,用于 tryLock 场景)
  84. * @param lock 锁对象
  85. */
  86. public static void unlock(RLock lock) {
  87. try {
  88. if (lock != null && lock.isLocked() && lock.isHeldByCurrentThread()) {
  89. lock.unlock();
  90. log.info("释放锁成功,lockKey: {}", lock.getName());
  91. } else {
  92. log.warn("释放锁失败,锁未被当前线程持有或已释放,lockKey: {}", lock.getName());
  93. }
  94. } catch (Exception e) {
  95. log.error("释放锁异常,lockKey: {}, 异常: {}", lock.getName(), e.getMessage());
  96. throw new RuntimeException("释放分布式锁失败", e);
  97. }
  98. }
  99. // 关闭 Redisson 客户端(项目关闭时调用)
  100. public static void shutdown() {
  101. if (instance.redissonClient != null) {
  102. instance.redissonClient.shutdown();
  103. log.info("Redisson 客户端已关闭");
  104. }
  105. }
  106. }