快手二面:Redisson公平锁用用过吗?他的实现原理是什么样子的?

文章内容收录到个人网站,方便阅读hardyfish.top/

Redisson 支持公平锁,实现类为:

Java 复制代码
RLock lock = redisson.getFairLock("myLock");

一、什么是公平锁?

公平锁表示: 多个线程在获取锁时,按照请求锁的先后顺序来获取锁,先申请锁的线程,先获得锁。

二、Redisson 公平锁的实现原理:

Redisson 的公平锁(Fair Lock)底层是基于 Redis数据结构(ZSet + List) 实现的,和普通锁(RLock)实现有差异:

Redisson 公平锁会用两个关键的 Redis 数据结构:

  • List队列,保存等待中的线程。
  • ZSet有序集合,保存线程等待锁的时间戳,用于排序,确保先请求锁的线程优先获得锁。

三、具体的实现细节:

当线程请求公平锁时:

  1. 尝试获取锁

    • 先判断锁是否空闲(Redis中key是否存在)。
    • 若锁空闲,且队列中无更早等待的线程,则立即获得锁。
    • 若锁已被占用或队列中已有其他等待线程,进入等待队列。
  2. 进入等待队列

    • 将线程唯一标识放入 Redis 的等待队列(List),同时在 ZSet 中记录线程请求锁的当前时间戳。
    • 然后订阅对应的 Redis channel,等待被唤醒。
  3. 释放锁

    • 当前持锁线程释放锁时,从队列头取出下一个等待线程,并发布消息到 channel,唤醒队首的线程。

四、Redisson 公平锁数据结构举例(伪代码):

例如:

makefile 复制代码
# 公平锁的Key名假设为 myLock
myLock:threadQueue (List结构)
myLock:timeout (ZSet结构)
​
List:
myLock:threadQueue = [threadA_UUID, threadB_UUID, threadC_UUID]
​
ZSet:
myLock:timeout = {
    threadA_UUID : 1700000000001,  # 请求时间戳
    threadB_UUID : 1700000000100,
    threadC_UUID : 1700000000200
}
  • 当锁释放后,Redisson取出threadQueue中的第一个元素threadA_UUID,唤醒对应线程继续获取锁。

五、公平锁的主要特点:

  • 避免饥饿现象:绝对公平,先到先得。
  • 性能开销略大:相比普通锁,需要维护额外的数据结构(ZSet + List),因此性能略低一些。

六、注意事项:

  • 公平锁适合于明确要求先到先服务的场景(如排队购票、秒杀顺序要求严格的场景)。
  • 如果不需要严格的公平性,建议使用性能更高的非公平锁(Redisson默认的RLock实现)。

七、示例代码:

Java 复制代码
RLock fairLock = redisson.getFairLock("myFairLock");
try {
    fairLock.lock();
    // 业务逻辑...
} finally {
    fairLock.unlock();
}

总结:

Redisson的公平锁:

  • 基于 Redis的List和ZSet实现
  • 通过队列和时间戳排序,确保公平性;
  • 会带来一定的性能开销,但能很好地避免饥饿问题;
  • 不再使用时自动释放资源,业务无需关心底层细节。
相关推荐
计算机学长felix19 小时前
基于SpringBoot的“面向校园的助力跑腿系统”的设计与实现(源码+数据库+文档+PPT)
数据库·spring boot·后端
fat house cat_19 小时前
【netty】基于主从Reactor多线程模型|如何解决粘包拆包问题|零拷贝
java·服务器·网络·netty
青云交19 小时前
Java 大视界 -- Java 大数据在智能教育学习社区互动模式创新与用户活跃度提升中的应用(426)
java·大数据·学习·flink 实时计算·智能教育社区·互动模式创新·用户活跃度
神奇的海马体19 小时前
Tomcat隐藏版本号
java·tomcat
拜见老天師19 小时前
使用mybatis-plus,实现将排序时,字段值为NULL的数据排在最后
java·mybatis
紫荆鱼19 小时前
设计模式-迭代器模式(Iterator)
c++·后端·设计模式·迭代器模式
应茶茶20 小时前
C++11 核心新特性:从语法重构到工程化实践
java·开发语言·c++
RainSky_20 小时前
LNMP 一键安装包部署 Django 项目
后端·django·1024程序员节
追逐时光者20 小时前
一个开源免费、轻量级的 Avalonia UI 控件库
后端·.net
Reggie_L20 小时前
RabbitMQ -- 高级特性
java·rabbitmq·java-rabbitmq