# redission-example **Repository Path**: fix-bugs/redission-example ## Basic Information - **Project Name**: redission-example - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-02-02 - **Last Updated**: 2026-02-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Redisson分布式锁 Redisson 是一个基于 Redis 的 Java 驻内存数据网格(In-Memory Data Grid),其 RLock 提供了功能强大的分布式锁,常用于高并发场景下的数据一致性保护。 其核心场景包括:秒杀/防超卖、分布式任务调度、高并发下的缓存一致性保护、定时任务锁定(防止集群多节点同时执行)。 通过 Lua 脚本和看门狗(Watchdog)机制,Redisson 实现了锁的可重入和自动续期。 ### Lock ```java RLock lock = redisson.getLock("myLock"); // traditional lock method lock.lock(); // or acquire lock and automatically unlock it after 10 seconds lock.lock(10, TimeUnit.SECONDS); // or wait for lock acquisition up to 100 seconds and auto-unlock after 10 seconds boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS); if (res) { try { // ... } finally { lock.unlock(); } } ``` ### Fair Lock 公平锁 Redisson Fair Lock(公平锁) 基于 Redis 实现,确保等待锁的线程按照先进先出(FIFO)顺序获取锁。适用于对请求顺序有严格要求、需防止线程饥饿的场景(如排队购票、高优先级任务处理)。其通过 Redis 列表记录排队顺序,性能低于非公平锁。 使用场景 - 有序队列处理:确保请求按到达顺序处理,例如公平的购票系统或银行转账顺序。 - 防止饥饿:避免某些线程长时间获取不到锁,保证所有等待线程最终都能获得资源。 - 顺序任务执行:需严格按请求顺序执行的任务,如分布式环境下的日志同步或报表生成。 ```java RLock lock = redisson.getFairLock("myLock"); // traditional lock method lock.lock(); // or acquire lock and automatically unlock it after 10 seconds lock.lock(10, TimeUnit.SECONDS); // or wait for lock acquisition up to 100 seconds // and automatically unlock it after 10 seconds boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS); if (res) { try { ... } finally { lock.unlock(); } } ``` ### MultiLock 联锁 Redisson 的 MultiLock(联锁)用于在分布式环境中同时对多个 Redis 资源(锁)加锁,保证“要么全部成功,要么全部失败”,适用于资金转账、库存调拨等涉及多个独立互斥资源必须保持强一致性的场景。 使用场景: - 资金跨行转账:锁定账户A和账户B,防止双向资金操作冲突。 - 复杂业务流程:同时更新库存和优惠券,需要同时对两个 Redis Key 加锁。 - 跨机房/节点:涉及多个物理 Redis 实例的资源同步。 ```java RLock lock1 = redisson1.getLock("lock1"); RLock lock2 = redisson2.getLock("lock2"); RLock lock3 = redisson3.getLock("lock3"); RLock multiLock = anyRedisson.getMultiLock(lock1, lock2, lock3); // traditional lock method multiLock.lock(); // or acquire lock and automatically unlock it after 10 seconds multiLock.lock(10, TimeUnit.SECONDS); // or wait for lock acquisition up to 100 seconds // and automatically unlock it after 10 seconds boolean res = multiLock.tryLock(100, 10, TimeUnit.SECONDS); if (res) { try { ... } finally { multiLock.unlock(); } } ``` ### RedLock 红锁,已弃用 This object is deprecated. Refer to this article for more details. Superseded by RLock and RFencedLock objects. ### ReadWriteLock 读写锁 Redisson 的 ReadWriteLock (读写锁) 适用于读多写少的分布式场景,如缓存更新、配置中心同步,通过“共享读、排他写”提高并发效率。允许多个线程同时读,但写锁会排斥其他所有读和写操作。示例代码包含读锁和写锁的加锁与释放操作。 使用场景: - 缓存与数据库同步:多个节点并发读取缓存,若缓存失效,仅需一个节点更新缓存,其余等待。 - 高频配置读取:系统配置热更新,后台管理系统修改配置(写锁),前台服务快速读取(读锁)。 ```java RReadWriteLock rwlock = redisson.getReadWriteLock("myLock"); RLock lock = rwlock.readLock(); // or RLock lock = rwlock.writeLock(); // traditional lock method lock.lock(); // or acquire lock and automatically unlock it after 10 seconds lock.lock(10, TimeUnit.SECONDS); // or wait for lock acquisition up to 100 seconds // and automatically unlock it after 10 seconds boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS); if (res) { try { ... } finally { lock.unlock(); } } ``` ### Semaphore 信号量 Redisson 的 RSemaphore 是基于 Redis 的分布式信号量,用于控制多节点环境下共享资源的并发访问量或进行限流。 适用于:限制接口并发请求数、分布式服务流量削峰、限制数据库/文件等资源连接数。通过 tryAcquire() 获取许可,release() 释放许可,实现分布式环境下的并发控制。 使用场景 - 接口限流:限制某个 API 在特定时间内的并发调用数。 - 资源池限制:限制对数据库连接池、外部接口的并发连接数。 - 分布式任务调度:限制同一时间只能有 (N) 个分布式节点执行任务。 ```java RSemaphore semaphore = redisson.getSemaphore("mySemaphore"); // acquire single permit semaphore.acquire(); // or acquire 10 permits semaphore.acquire(10); // or try to acquire permit boolean res = semaphore.tryAcquire(); // or try to acquire permit or wait up to 15 seconds boolean res = semaphore.tryAcquire(15, TimeUnit.SECONDS); // or try to acquire 10 permits boolean res = semaphore.tryAcquire(10); // or try to acquire 10 permits or wait up to 15 seconds boolean res = semaphore.tryAcquire(10, 15, TimeUnit.SECONDS); if (res) { try { ... } finally { semaphore.release(); } } ``` ### PermitExpirableSemaphore 带过期时间的许可信号量 Redisson 的 PermitExpirableSemaphore(带过期时间的许可信号量)适用于需要控制并发数且许可必须在一定时间后自动释放的场景,如限流、临时授权、防止死锁的资源占用。它为每个许可提供独立的过期时间,若持有人未释放,许可会自动归还。 核心使用场景 - 限流/配额管理:例如,每日限售某种优惠券 100 张,用户领取后 1 小时内未付款则自动退回配额。 - 分布式临时授权:允许特定数量的临时任务并发执行,任务超时自动释放许可供其他任务使用。 ```java RPermitExpirableSemaphore semaphore = redisson.getPermitExpirableSemaphore("mySemaphore"); semaphore.trySetPermits(23); // acquire permit String id = semaphore.acquire(); // or acquire permit with lease time in 10 seconds String id = semaphore.acquire(10, TimeUnit.SECONDS); // or try to acquire permit String id = semaphore.tryAcquire(); // or try to acquire permit or wait up to 15 seconds String id = semaphore.tryAcquire(15, TimeUnit.SECONDS); // or try to acquire permit with lease time 15 seconds or wait up to 10 seconds String id = semaphore.tryAcquire(10, 15, TimeUnit.SECONDS); if (id != null) { try { ... } finally { semaphore.release(id); } } ``` ### CountDownLatch 计数器 Redisson的RCountDownLatch是基于Redis的分布式同步工具,适用于多节点集群环境下,一个线程(或服务)需等待其他多个节点完成操作后再继续的场景,如分布式任务汇总、高并发下服务启动倒计时等。其核心在于通过countDown()减少计数,await()阻塞等待直到计数为0。 使用场景 多任务汇总:一个主服务将大任务拆分为多个子任务,分布式部署在不同节点上执行,主服务需要等待所有子任务完成才能汇总结果。 高并发启动:服务启动时需要预热数据,等待多个初始化子服务完成后再对外提供服务。 ```java RCountDownLatch latch = redisson.getCountDownLatch("myCountDownLatch"); latch.trySetCount(1); // await for count down latch.await(); // in other thread or JVM RCountDownLatch latch = redisson.getCountDownLatch("myCountDownLatch"); latch.countDown(); ``` ### Spin Lock 自旋锁 Redisson 自旋锁(SpinLock)适用于高并发、锁持有时间极短(如内存操作、快速扣减库存)的场景。它通过循环尝试获取锁,避免线程上下文切换开销,比阻塞锁更高效。使用时通过RedissonSpinLock类或设置LockOptions实现,需设置合理超时时间以防死锁。 使用场景 极高并发的快速操作:如抢红包、秒杀扣减库存、短时间内的计数器递增。 锁持有时间短:锁内的业务逻辑执行速度极快(毫秒级)。 不希望线程阻塞:希望在尝试获取锁失败后,不进入休眠状态,立即进行下一次尝试。 - 非阻塞:自旋锁不挂起线程,减少了线程切换的内核态开销。 - 自适应:适合高并发下锁的持有时间小于线程挂起/唤醒耗时。 - 高 CPU 占用:若锁被长时间持有,自旋锁会消耗大量 CPU 资源进行空转,需谨慎使用。 ```java RLock lock = redisson.getSpinLock("myLock"); // traditional lock method lock.lock(); // or acquire lock and automatically unlock it after 10 seconds lock.lock(10, TimeUnit.SECONDS); // or wait for lock acquisition up to 100 seconds // and automatically unlock it after 10 seconds boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS); if (res) { try { ... } finally { lock.unlock(); } } ``` ### Fenced Lock 围栏锁/带令牌的分布式锁 Redisson 的 Fenced Lock (围栏锁/带令牌的分布式锁) 是一种增强型分布式锁,通过在获取锁时生成递增的令牌(Fence Token),专门用于解决在分布式系统中由于 GC 停顿、网络延迟导致锁超时释放,从而引发的“锁失效”并发安全问题。它常用于高并发、对数据一致性要求极高的场景,例如数据库乐观锁升级、分布式事务数据最终一致性保障。 一、使用场景 强一致性数据更新:如扣减库存、余额,配合数据库的“版本号”或“时间戳”进行对比,拒绝旧请求。 分布式任务调度:确保某一时间只有一个节点在处理特定任务,且在前一个任务节点假死后,后一个任务节点能安全接管。 防止缓存与数据库不一致:在写数据库时通过 Fenced Lock 确保顺序,避免并发下的老数据覆盖新数据。 - Token 机制:lock.lock() 返回一个 long 类型的令牌。如果线程 A 获取令牌 10,因 GC 挂起;线程 B 获取令牌 11 并完成操作。当线程 A 恢复后继续操作,利用其旧令牌 10 与 11 对比,可识别出自己已过时,从而阻止脏数据写入。 - 与普通锁区别:普通 RLock 仅防止并发进入,不能保证锁超时后的数据安全性;RFencedLock 通过令牌机制保证了在分布式环境下的写安全。 - 看门狗 (Watchdog):同普通锁,Redisson 也会在 RFencedLock 持有期间自动续期,防止任务未完成锁就失效 ```java RFencedLock lock = redisson.getFencedLock("myLock"); // traditional lock method Long token = lock.lockAndGetToken(); // or acquire lock and automatically unlock it after 10 seconds token = lock.lockAndGetToken(10, TimeUnit.SECONDS); // or wait for lock acquisition up to 100 seconds // and automatically unlock it after 10 seconds Long token = lock.tryLockAndGetToken(100, 10, TimeUnit.SECONDS); if (token != null) { try { // check if token >= old token ... } finally { lock.unlock(); } } ```