Redisson公平锁实现原理!
Redisson公平锁实现原理!
月伴飞鱼Redisson 支持公平锁,实现类为:
1 | RLock lock = redisson.getFairLock("myLock"); |
什么是公平锁?
公平锁表示多个线程在获取锁时,按照请求锁的先后顺序来获取锁,先申请锁的线程,先获得锁。
Redisson公平锁的实现原理:
Redisson 的公平锁(Fair Lock)底层是基于 Redis数据结构(ZSet + List) 实现的。
,和普通锁(RLock)实现有差异。
Redisson 公平锁会用两个关键的 Redis 数据结构:
List
:队列,保存等待中的线程。
ZSet
:有序集合,保存线程等待锁的时间戳,用于排序,确保先请求锁的线程优先获得锁。
具体的实现细节:
当线程请求公平锁时:
尝试获取锁
- 先判断锁是否空闲(Redis中key是否存在)。
- 若锁空闲,且队列中无更早等待的线程,则立即获得锁。
- 若锁已被占用或队列中已有其他等待线程,进入等待队列。
进入等待队列
- 将线程唯一标识放入 Redis 的等待队列(List),同时在 ZSet 中记录线程请求锁的当前时间戳。
- 然后订阅对应的 Redis Channel,等待被唤醒。
释放锁
- 当前持锁线程释放锁时,从队列头取出下一个等待线程,并发布消息到 Channel,唤醒队首的线程。
Redisson 公平锁数据结构举例(伪代码):
例如:
1 | # 公平锁的Key名假设为 myLock |
当锁释放后,Redisson取出
threadQueue
中的第一个元素threadA_UUID
,唤醒对应线程继续获取锁。
公平锁的主要特点:
避免饥饿现象:绝对公平,先到先得。
性能开销略大:相比普通锁,需要维护额外的数据结构(ZSet + List),因此性能略低一些。
注意事项:
公平锁适合于明确要求先到先服务的场景(如排队购票、秒杀顺序要求严格的场景)。
如果不需要严格的公平性,建议使用性能更高的非公平锁(Redisson默认的
RLock
实现)。
示例代码:
1 | RLock fairLock = redisson.getFairLock("myFairLock"); |
总结:
Redisson的公平锁:
- 基于 Redis的List和ZSet实现。
- 通过队列和时间戳排序,确保公平性。
- 会带来一定的性能开销,但能很好地避免饥饿问题。
- 不再使用时自动释放资源,业务无需关心底层细节。