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 是分布式系统中控制并发的利器,但一定要合理设计超时机制,避免死锁和性能问题! 🚀

相关推荐
程序员黑豆5 小时前
Java类型推断完全指南:从var到菱形运算符,掌握使用限制与最佳实践
java·前端·ai编程
GreenTea6 小时前
深度解读 Anthropic 多智能体报告:更强的模型 ≠ 更好的协调
前端·后端·算法
风流 少年6 小时前
Spring AI 2.0:Memory
java·后端·spring
码匠许师傅6 小时前
【C++ 面试真题】聊聊 C++ 的移动语义与右值引用
java·c++·面试
万少6 小时前
给 DeepSeek Harness 装个"应用商店":一条命令,595 个插件随你逛
前端·javascript·后端
小席是个热心肠6 小时前
AI相关的自我学习
java·人工智能·学习
数智化管理手记9 小时前
海量数据如何沉淀有效数据资产?数据标准化治理方案如何搭建?
java·大数据·人工智能
cfm_29149 小时前
SpringAI + Ollama 本地大模型
java·开发语言·人工智能·语言模型
鲸采云SRM采购管理系统10 小时前
采购管理系统哪家好?2026最新测评对比
java·服务器·数据库
IT_陈寒10 小时前
Python的GIL让我多写了500行代码
前端·人工智能·后端