从算法 + 数据结构 + 规则,解释一下Redisson分布式锁
很多开发者使用 Redisson 时,只知道调用 lock() 和 unlock(),却不清楚其内部原理。 实际上,可以从 算法(Algorithm)、数据结构(Data Structure) 和 规则(Rule) 三个维度来理解 Redisson 分布式锁。
Redisson 的锁本质上是 Redis 中的一个 Key。
当线程获得锁后,Redis 会记录:
- 持有锁的线程标识(UUID + ThreadId)
- 重入次数(Reentrant Count)
- 锁的过期时间(TTL)
例如:
field:UUID:threadId
value:3
这里的 value=3 表示当前线程已经重入了 3 次。
Redisson 使用 Lua 脚本完成加锁操作。
创建锁
设置 TTL
返回成功
如果锁存在
判断是否当前线程
是 → 重入次数 +1
否 → 返回失败
由于 Redis 单线程执行 Lua,因此整个过程具有原子性。
很多人以为 Redisson 获取不到锁时会一直 while(true) 轮询 Redis。
实际上并不是。
获取失败后,线程会订阅一个 Channel:
锁释放时发布消息,等待线程被唤醒后重新竞争锁。
✅ 优点:减少 Redis 压力。
✅ 优点:降低 CPU 消耗。
如果执行:
默认锁过期时间为 30 秒。
为了避免业务执行超过 30 秒导致锁失效,Redisson 会启动 WatchDog。
自动续期一次
本质上是一种心跳续约机制。
同一时刻只能有一个线程持有锁。
✅ 保证共享资源安全。
❌ 不允许多个线程同时修改同一数据。
同一个线程可以重复获取同一把锁。
lock();
lock();
unlock();
unlock();
unlock();
只有重入次数减到 0 时,锁才真正释放。
每把锁都有 TTL。
即使应用崩溃:
❌ 没有执行 unlock()。
✅ Redis 到期后仍会自动释放锁。
只有锁的持有者才能解锁。
↓
Lua 抢锁
↓
获取成功
↓
执行业务
↓
WatchDog 自动续期
↓
unlock()
↓
发布解锁消息
↓
唤醒等待线程
Redisson 分布式锁本质上是:
使用 Redis 保存锁状态,使用 Lua 保证原子性,使用 Pub/Sub 实现等待与唤醒,使用 WatchDog 保证锁不会意外过期。
一句话总结:
相关文章
-
CMS与G1的区别?
1、CMS是老年代回收器,可以配合其它Serial和ParNew收集器一起使用。 2、G1是全局范围的,不需要配合其它垃圾器使用
NEW个对象 2025-01-09
-
线程和进程的区别?
线程和进程的区别?
NEW个对象 2025-01-09
-
JVM常见的配置参数
JVM常见的配置参数
NEW个对象 2025-01-09