当前位置: 首页 > article >正文

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

概述

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


1. RLock 详解

🔹 特点

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

🔹 依赖

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.22.1</version>
</dependency>

🔹 获取 RLock

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)同时访问共享资源时,防止并发冲突。

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

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. 限制用户重复提交

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

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. 分布式定时任务的幂等控制

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

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

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

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

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 分钟未支付,自动取消订单。

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

示例:读写锁

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

6. 总结

RLock 是基于 Redis 实现的分布式锁,适用于高并发环境
支持可重入、超时释放、WatchDog 续期
适用于库存扣减、订单防重、定时任务、秒杀等场景
如果需要更高可靠性,可使用 RedLock

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


http://www.kler.cn/a/576245.html

相关文章:

  • MySQL如何创建索引 MySQL 创建索引详解:提升查询性能的利器
  • SpringBoot - 用责任链模式实现业务编排
  • Hive-优化(语法优化篇)
  • javaweb:Maven、SpringBoot快速入门、HTTP协议
  • Tomcat 新手入门指南:从零开始掌握安装与配置
  • RocketMQ延迟消息深度解析:原理、实践与性能调优
  • 【JAVA架构师成长之路】【持久层】第2集:SQL常用优化手段
  • 【C++设计模式】第八篇:组合模式(Composite)
  • 深入探讨AI-Ops架构 第一讲 - 运维的进化历程以及未来发展趋势
  • redisinsight 默认端口改成5540了
  • OpenCV计算摄影学(17)两个图像之间执行无缝克隆操作函数 seamlessClone()
  • maven高级-05.私服
  • 【银河麒麟高级服务器操作系统实例】虚拟机桥接网络问题分析及处理
  • Linux驱动开发(1.基础创建)
  • ❌Manus?✅OpenManus + DeepSeek!!!
  • springboot项目使用中创InforSuiteAS替换tomcat
  • pandas-基础(数据结构及文件访问)
  • BP神经网络终极进化:2025量子增强版Python实现(附元宇宙金融实战)
  • 深度学习(斋藤康毅)学习笔记(六)反向传播3
  • C#实现应用程序单个运行,防止重复启动