Redisson常用方法深度解析:从“瑞士军刀”到“锁界变形金刚”

328 阅读4分钟

一、分布式锁(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();  

应用:监控锁的健康状态,预警潜在死锁。


六、方法选择决策树


(决策树文字描述)

  1. 是否需要公平性? → 选公平锁。
  2. 是否需要同时锁多个资源? → 选联锁。
  3. 是否在Redis集群环境? → 选红锁。
  4. 是否需要非阻塞? → 用tryLock()或异步API。

七、总结:方法虽多,重在“对症下药”

  • 基础锁:覆盖90%场景,牢记tryLock+unlock范式。
  • 高级锁:按需选择公平锁、联锁,复杂场景用红锁。
  • 分布式工具:信号量、闭锁解决特定协调问题。
  • 异步API:高并发场景下的性能利器。

最后忠告

  • 像对待女朋友一样对待锁——用完及时释放
  • 像防贼一样防forceUnlock()——不到万不得已别用
  • 像关心健康一样监控锁——剩余时间+线程持有状态是关键指标!