SpringBoot分布式锁实现与使用指南
基于Redis的分布式锁工具tools-redis,支持注解与手动两种加锁方式,具备超时自动释放、可重入、自动续期及自定义扩展能力。建议配合单机Redis使用,避免Sentinel集群因主从同步延迟导致数据不一致,适用于高并发场景下的互斥控制。
在项目开发中,并发安全始终是一个不可忽视的挑战。单机环境下,通过 synchronized 或 Lock 可以轻松实现线程同步。然而,一旦系统迁移到分布式架构,这些本地锁便无法发挥作用——不同机器上的线程彼此孤立,无法感知对方的存在。此时,我们需要借助中间件(例如 Redis)来实现一把全局的分布式锁,从而有效应对分布式场景下的并发问题。
一款基于 Redis 的分布式锁工具——tools-redis
本文介绍一款轻量级、开源的 Redis 分布式锁实现工具——tools-redis。它支持开箱即用,提供注解与手动两种锁控制方式,内置超时处理机制,并允许自定义扩展,能够满足大多数分布式锁的应用需求。
一、引入 Maven 依赖
cn.gjing tools-redis 1.2.0
二、在启动类上启用分布式锁注解
@SpringBootApplication
@EnableToolsLock
public class TestRedisApplication {
public static void main(String[] args) {
SpringApplication.run(TestRedisApplication.class, args);
}
}
三、具体使用方式
1、注解方式
在需要加锁的方法上添加 @Lock 注解即可,简单快捷,无需额外代码。
@RestController
public class TestController {
private static int num = 20;
@GetMapping("/test1")
@Lock(key = "test1")
public void test1() {
System.out.println("当前线程:" + Thread.currentThread().getName());
if (num == 0) {
System.out.println("卖完了");
return;
}
num--;
System.out.println("还剩余:" + num);
}
}
参数说明
| 参数 | 描述 |
|---|---|
| key | 锁的key,建议每个方法保持唯一性 |
| expire | 锁的过期时间,单位为秒,默认值为5 |
| timeout | 尝试获取锁的超时时间,单位为毫秒,默认值为500 |
| retry | 重新获取锁的间隔时间,单位为毫秒,默认值为10 |
使用 ab 压测工具测试的结果如下
2、手动控制方式
在需要使用锁的类中注入 AbstractLock,然后通过代码手动控制加锁与解锁,灵活性更高。
a、lock():加锁
成功获取锁后返回一个用于解锁的值,失败则返回 null。
abstractLock.lock(key, expire, timeout, retry)
参数说明
| 参数 | 描述 |
|---|---|
| key | 锁的key,每个方法应保证唯一性 |
| expire | 锁的过期时间,单位为秒,默认值为5 |
| timeout | 尝试获取锁的超时时间,单位为毫秒,默认值为500 |
| retry | 重新获取锁的间隔时间,单位为毫秒,默认值为10 |
b、release():解锁
成功释放锁后返回当前被解锁的 key,失败则返回 null。
abstractLock.release(key, value)
参数说明
| 参数 | 描述 |
|---|---|
| key | 加锁时对应的key |
| value | 获取锁成功后得到的值 |
使用示例
@RestController
public class LockController {
@Resource
private AbstractLock abstractLock;
private static int num = 10;
@GetMapping("/test2")
public void test2() {
String lock = null;
try {
lock = this.abstractLock.lock("testLock", 20, 10000, 50);
System.out.println("当前线程:" + Thread.currentThread().getName());
if (num == 0) {
System.out.println("卖完了");
return;
}
num--;
System.out.println("还剩余:" + num);
} finally {
this.abstractLock.release("testLock", lock);
}
}
}
ab 压测结果
3、自定义超时处理
当获取锁超时时,默认会抛出超时异常。若需要自定义逻辑,可以继承 AbstractLockTimeoutHandler 并实现自己的处理方法。
@Component
public class TimeoutHandler extends AbstractLockTimeoutHandler {
@Override
public void getLockTimeoutFallback(String s, int i, int i1, int i2) {
// TODO: 自定义处理逻辑
}
}
4、自定义锁实现
@Component
public class DemoLock extends AbstractLock {
@Override
public String lock(String s, String s1, int i, int i1, int i2) {
return null;
}
@Override
public String release(String s, String s1) {
return null;
}
}
四、使用建议
建议将此分布式锁与单机 Redis 配合使用。如果部署在 Redis Sentinel 集群中,需要充分考虑潜在风险:Sentinel 架构采用一主多从模式,数据先写入主库再同步到从库。假设在主库上执行 setnx mykey myvalue 成功,但数据尚未同步到从库时主库宕机,Sentinel 会从从库中选举新的主库。此时新主库中不存在 mykey,另一个客户端再执行 setnx mykey hisvalue 也会成功,导致两个客户端同时持有锁,破坏数据一致性。因此,在 Sentinel 环境下使用需谨慎评估。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
CAD零基础入门教程:坐标输入、图层管理与基础绘图命令
本文面向CAD零基础学习者,系统讲解坐标输入、图层管理与基础绘图命令的核心用法。通过分步实操与常见问题排查,帮助新手建立精确绘图习惯,掌握规范出图的基础能力。
CAD从入门到项目交付:绘图、标注、图块与实战工作流
掌握CAD的核心在于建立“画得准、标得清、复用快、交付稳”的工作流。本文提供从环境设置、高频命令组合、标注规范、图块标准化到项目分阶段交付的完整路径,帮助初学者避免常见返工陷阱,独立完成可检查、可复用、可打印的工程图纸。
Claude Code 登录指南:个人、Teams 与企业账号区分与授权步骤
本文详细解析 Claude Code 登录前的账号类型区分方法,涵盖个人订阅、Teams 席位与企业 Enterprise 席位的授权路径差异。提供终端登录命令、环境变量排查及常见异常处理步骤,帮助用户快速完成正确授权并避免登录路径混淆。
Claude Code 文件修改前的权限模式配置与命令审批指南
本文详细介绍Claude Code在修改文件前的权限模式配置方法,包括defaultMode可选值、permissions allow与deny规则设置、多层级配置文件管理以及 status验证技巧,帮助开发者安全高效地使用AI编程助手。
Claude Code接入VS Code后先测扩展和终端命令
在VS Code中接入Claude Code后,建议优先验证扩展面板与集成终端两条入口。本文提供标准检查顺序、关键命令与常见故障排查路径,帮助你快速确认环境就绪,避免后续开发受阻。
- 热门数据榜
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
相关攻略
2026-09-01 16:53
2026-09-01 16:52
2026-09-01 14:27
2026-09-01 14:12
2026-09-01 14:10
2026-09-01 14:07
2026-09-01 13:55
2026-09-01 13:47
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程

