RLock类详细介绍、应用场景和示例代码

概述

org.redisson.api.RLock 是 Redisson 提供的 分布式可重入锁 (类似 ReentrantLock),基于 Redis 实现,常用于 分布式环境 下的 并发控制


1. RLock 详解

🔹 特点

  • 基于 Redis 实现 ,支持 集群环境
  • 可重入,同一个线程可以多次获取同一把锁,不会被阻塞。
  • 支持 WatchDog 机制,避免锁因宕机未手动释放而导致死锁。
  • 支持超时自动释放,避免死锁问题。
  • 支持公平锁、联锁、红锁等多种高级特性

🔹 依赖

XML 复制代码
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.22.1</version>
</dependency>

🔹 获取 RLock

java 复制代码
RedissonClient redissonClient = Redisson.create(); // 需要传入 Redis 配置
RLock lock = redissonClient.getLock("myLock");

2. RLock 常用方法

方法 说明
lock() 阻塞式加锁(默认 WatchDog 续期)
lock(long leaseTime, TimeUnit unit) 加锁 + 设定过期时间,到期自动释放
tryLock() 非阻塞式 ,如果获取不到锁立即返回 false
tryLock(long waitTime, long leaseTime, TimeUnit unit) 尝试获取锁 ,最长等待 waitTime,成功后 leaseTime 过期自动释放
unlock() 释放锁
isLocked() 判断锁是否被任意线程占用
isHeldByCurrentThread() 判断当前线程是否持有锁
forceUnlock() 强制释放锁,无论是谁持有锁

3. RLock 典型应用场景

1. 解决分布式环境下的并发问题

多个服务实例(如 AB)同时访问共享资源时,防止并发冲突。

场景:多个线程同时对某个商品库存进行扣减操作,需要防止超卖。

java 复制代码
public void reduceStock() {
    RLock lock = redissonClient.getLock("product_stock_lock");
    try {
        lock.lock();  // 加锁(默认30s自动续期)
        int stock = getStock();
        if (stock > 0) {
            updateStock(stock - 1);
        }
    } finally {
        lock.unlock(); // 释放锁
    }
}

⚠ 注意 :如果 lock.lock() 后方法抛异常,未执行 unlock(),Redisson 默认使用 WatchDog 机制自动续期,不会发生死锁。


2. 限制用户重复提交

场景:用户短时间内重复提交订单,导致重复下单。

java 复制代码
public String submitOrder(String userId) {
    RLock lock = redissonClient.getLock("order_lock:" + userId);
    boolean success = lock.tryLock();
    if (!success) {
        return "请勿重复提交";
    }
    try {
        processOrder();
        return "订单提交成功";
    } finally {
        lock.unlock();
    }
}

3. 分布式定时任务的幂等控制

场景:多个定时任务实例同时启动,保证同一时间只有一个任务执行。

java 复制代码
public void executeTask() {
    RLock lock = redissonClient.getLock("task_lock");
    if (!lock.tryLock()) {
        return; // 其他实例已持有锁,当前实例不执行任务
    }
    try {
        performTask();
    } finally {
        lock.unlock();
    }
}

4. 秒杀场景:高并发库存扣减

场景:多用户高并发秒杀商品,避免超卖。

java 复制代码
public boolean secKill(String productId) {
    RLock lock = redissonClient.getLock("sec_kill_lock:" + productId);
    try {
        if (lock.tryLock(100, 10, TimeUnit.MILLISECONDS)) {
            int stock = getStock(productId);
            if (stock > 0) {
                updateStock(productId, stock - 1);
                return true;
            }
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }
    return false;
}

🔹 关键点

  • tryLock(100, 10, TimeUnit.MILLISECONDS)
    • 等待最长 100ms 获取锁
    • 持有锁 10ms 后自动释放
  • 适用于高并发业务,防止 Redis 长时间占用锁资源。

5. 订单支付超时取消

场景:订单创建 30 分钟未支付,自动取消订单。

java 复制代码
public void setOrderExpire(String orderId) {
    RLock lock = redissonClient.getLock("order_expire_lock:" + orderId);
    lock.lock(30, TimeUnit.MINUTES); // 30 分钟后自动释放锁
}

4. RLock 可能存在的问题

问题 解决方案
锁未释放(死锁) 1️⃣ lock.lock(leaseTime, TimeUnit.SECONDS) 设置超时 2️⃣ 使用 WatchDog 机制
Redis 宕机,锁丢失 采用 Redis 主从 + 哨兵 ,或者使用 Redisson RedLock
线程异常退出,锁未释放 1️⃣ try-finally 释放锁 2️⃣ lock.lock(leaseTime, TimeUnit.SECONDS) 设定过期时间
多个服务实例并发竞争锁 使用 tryLock(waitTime, leaseTime, TimeUnit.SECONDS)

5. 进阶:Redisson 其他锁

锁类型 说明
RLock 可重入锁
RReadWriteLock 读写锁,读读共享,写独占
RFairLock 公平锁,先请求的先获得锁
RMultiLock 联锁 ,多个 RLock 绑定在一起
RedLock 红锁 ,适用于 Redis 主从集群
RSemaphore 信号量 ,类似 Java Semaphore
RCountDownLatch 分布式 CountDownLatch

示例:读写锁

java 复制代码
RReadWriteLock rwLock = redissonClient.getReadWriteLock("my_rw_lock");
rwLock.readLock().lock();
try {
    System.out.println("执行读操作...");
} finally {
    rwLock.readLock().unlock();
}

6. 总结

RLock 是基于 Redis 实现的分布式锁,适用于高并发环境

支持可重入、超时释放、WatchDog 续期

适用于库存扣减、订单防重、定时任务、秒杀等场景

如果需要更高可靠性,可使用 RedLock

🔥 RLock 是分布式系统中控制并发的利器,但一定要合理设计超时机制,避免死锁和性能问题! 🚀

相关推荐
程序员爱钓鱼28 分钟前
Go语言实战案例-创建模型并自动迁移
后端·google·go
javachen__33 分钟前
SpringBoot整合P6Spy实现全链路SQL监控
spring boot·后端·sql
uzong6 小时前
技术故障复盘模版
后端
GetcharZp6 小时前
基于 Dify + 通义千问的多模态大模型 搭建发票识别 Agent
后端·llm·agent
桦说编程7 小时前
Java 中如何创建不可变类型
java·后端·函数式编程
lifallen7 小时前
Java Stream sort算子实现:SortedOps
java·开发语言
IT毕设实战小研7 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
wyiyiyi7 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
没有bug.的程序员8 小时前
JVM 总览与运行原理:深入Java虚拟机的核心引擎
java·jvm·python·虚拟机
一只爱撸猫的程序猿8 小时前
使用Spring AI配合MCP(Model Context Protocol)构建一个"智能代码审查助手"
spring boot·aigc·ai编程