在 Redisson 里,RLock
支持可重入锁、自动过期、阻塞等待等,使用起来跟 ReentrantLock
很像。
🚀 标准用法模板
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import java.util.concurrent.TimeUnit;
public class RedissonLockExample {
private final RedissonClient redissonClient;
public RedissonLockExample(RedissonClient redissonClient) {
this.redissonClient = redissonClient;
}
public void doBusiness() {
// 分布式锁 key(建议有业务前缀)
String lockKey = "lock:order:create";
// 获取 RLock
RLock lock = redissonClient.getLock(lockKey);
boolean isLocked = false;
try {
// tryLock 参数说明:
// 1. waitTime:等待获取锁的最大时间
// 2. leaseTime:锁自动释放时间(避免死锁)
// 3. timeUnit:时间单位
isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS);
if (isLocked) {
// ===============================
// 🟢 成功获取到锁,执行业务逻辑
// ===============================
System.out.println("获取锁成功,执行业务逻辑...");
Thread.sleep(5000); // 模拟业务处理
} else {
// ===============================
// 🔴 没有获取到锁,做降级处理
// ===============================
System.out.println("未获取到锁,稍后重试或丢弃请求");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("获取锁时被中断", e);
} finally {
// ===============================
// ✅ 必须释放锁(只有自己持有的锁才能释放)
// ===============================
if (isLocked && lock.isHeldByCurrentThread()) {
lock.unlock();
System.out.println("释放锁成功");
}
}
}
}
🔑 核心要点
-
加锁方式
lock.lock()
→ 一直阻塞直到获取锁,可能导致死锁,不推荐。lock.tryLock(waitTime, leaseTime, TimeUnit)
→ 推荐,带超时和自动释放。lock.tryLock()
→ 非阻塞获取,拿不到立即返回false
。
-
leaseTime
- 必须设置,否则锁可能因为网络抖动一直占用,造成死锁。
- 典型设置:
30s
或比业务逻辑耗时略长一点。
-
finally 解锁
unlock()
必须放在finally
,且要判断lock.isHeldByCurrentThread()
。
-
锁 key 规范
业务模块:功能名:资源标识
例子:order:create:12345
,防止 key 冲突。
🔴 如果要用 RedLock 红锁
Redisson 提供 RedissonRedLock
,可以在多 Redis 节点上加锁,提升容错性:
RLock lock1 = redissonClient1.getLock("lock:order:create");
RLock lock2 = redissonClient2.getLock("lock:order:create");
RLock lock3 = redissonClient3.getLock("lock:order:create");
// 创建红锁(至少 N/2+1 成功才算加锁成功)
RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);
boolean isLocked = false;
try {
isLocked = redLock.tryLock(10, 30, TimeUnit.SECONDS);
if (isLocked) {
System.out.println("红锁加锁成功,执行业务逻辑...");
}
} finally {
if (isLocked) {
redLock.unlock();
}
}
👉 总结:
- 单 Redis 节点 → 用
RLock
就够了。 - 多 Redis 集群、高可用 → 用
RedissonRedLock
。