一、分布式锁(RLock):锁的“七十二变”
1. 基础锁操作
RLock lock = redissonClient.getLock("myLock");
// 阻塞式加锁(直到成功或线程中断)
lock.lock();
// 尝试加锁(非阻塞)
boolean isLocked = lock.tryLock();
// 带超时的尝试加锁
boolean isLocked = lock.tryLock(1, 10, TimeUnit.SECONDS);
// 解锁
lock.unlock();
场景:
lock():适用于必须等待锁的场景(如定时任务调度)。tryLock():高并发场景下快速失败,避免线程堆积(如秒杀系统)。
避坑:
- 若使用
lock()未设置超时,看门狗默认续期(需手动解锁)。 tryLock(0, ...)中等待时间设为0表示立即失败。
2. 高级锁特性
① 可重入锁(Reentrant Lock)
lock.lock();
try {
// 同一线程再次加锁
lock.lock();
// 业务代码...
} finally {
lock.unlock();
lock.unlock(); // 需解锁两次
}
原理:通过Hash结构记录线程ID和重入次数。
② 公平锁(Fair Lock)
RLock fairLock = redissonClient.getFairLock("fairLock");
fairLock.lock();
特点:按请求顺序分配锁,避免“线程饥饿”。
代价:性能略低于非公平锁(需维护队列)。
③ 联锁(MultiLock)
RLock lock1 = redissonClient.getLock("lock1");
RLock lock2 = redissonClient.getLock("lock2");
RedissonMultiLock multiLock = new RedissonMultiLock(lock1, lock2);
multiLock.lock();
场景:需同时获取多个锁时(如跨资源操作)。
④ 红锁(RedLock)
RLock lock1 = redissonClient.getLock("lock1");
RLock lock2 = redissonClient.getLock("lock2");
RLock lock3 = redissonClient.getLock("lock3");
RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);
redLock.lock();
用途:在Redis集群模式下增强锁可靠性(需多数节点加锁成功)。
二、分布式工具类:不止于锁
1. 信号量(Semaphore)
RSemaphore semaphore = redissonClient.getSemaphore("semaphore");
semaphore.trySetPermits(5); // 初始化5个许可
// 获取许可(阻塞)
semaphore.acquire();
// 尝试获取许可
boolean acquired = semaphore.tryAcquire(1, TimeUnit.SECONDS);
// 释放许可
semaphore.release();
场景:限制资源并发访问数(如数据库连接池控制)。
2. 闭锁(CountDownLatch)
RCountDownLatch latch = redissonClient.getCountDownLatch("latch");
latch.trySetCount(3); // 初始化计数器为3
// 等待计数器归零
latch.await();
// 其他线程减少计数
latch.countDown();
场景:分布式任务协同(如等待所有子任务完成)。
3. 原子长整型(AtomicLong)
RAtomicLong atomicLong = redissonClient.getAtomicLong("counter");
atomicLong.incrementAndGet(); // 原子递增
long value = atomicLong.get();
场景:分布式环境下的全局计数器(如订单号生成)。
三、异步与 Reactive API:性能“加速器”
1. 异步锁
RFuture<Boolean> future = lock.tryLockAsync(1, 10, TimeUnit.SECONDS);
future.whenComplete((res, ex) -> {
if (res) {
// 加锁成功
}
});
优势:非阻塞调用,适合高吞吐场景(如响应式编程)。
2. Reactive API
RedissonReactiveClient redissonReactive = Redisson.createReactive(config);
redissonReactive.getLock("reactiveLock")
.tryLock()
.subscribe(res -> {
if (res) {
// 加锁成功
}
});
适用:Spring WebFlux等响应式框架集成。
四、看门狗机制:锁的“续命丹”
1. 自动续期逻辑
- 触发条件:使用
lock()或tryLock()时不指定leaseTime参数。 - 续期规则:默认每10秒检查一次,将锁过期时间重置为30秒。
2. 手动控制续期
// 强制设置锁过期时间(禁用看门狗)
lock.lock(30, TimeUnit.SECONDS);
适用场景:明确知道业务最大耗时。
五、实战技巧:方法背后的“小心机”
1. 锁的forceUnlock():慎用!
lock.forceUnlock(); // 强制释放锁,无视持有者
风险:可能导致数据不一致,仅用于紧急恢复。
2. 查询锁状态
boolean isLocked = lock.isLocked();
boolean isHeldByCurrentThread = lock.isHeldByCurrentThread();
用途:调试时检查锁状态,生产环境慎用(状态可能瞬时变化)。
3. 锁的剩余时间
long remainTime = lock.remainTimeToLive();
应用:监控锁的健康状态,预警潜在死锁。
六、方法选择决策树
(决策树文字描述)
- 是否需要公平性? → 选公平锁。
- 是否需要同时锁多个资源? → 选联锁。
- 是否在Redis集群环境? → 选红锁。
- 是否需要非阻塞? → 用
tryLock()或异步API。
七、总结:方法虽多,重在“对症下药”
- 基础锁:覆盖90%场景,牢记
tryLock+unlock范式。 - 高级锁:按需选择公平锁、联锁,复杂场景用红锁。
- 分布式工具:信号量、闭锁解决特定协调问题。
- 异步API:高并发场景下的性能利器。
最后忠告:
- 像对待女朋友一样对待锁——用完及时释放!
- 像防贼一样防
forceUnlock()——不到万不得已别用! - 像关心健康一样监控锁——剩余时间+线程持有状态是关键指标!