【redis】redis分布式锁(二)可重入锁
文章目录
- 【redis】redis分布式锁(二)可重入锁
- 前言
- 一、可重入锁(又名递归锁)
- 1、说明:
- 2、分开解释:
- 3、可重入锁的种类
- 隐式锁(即synchronized关键字使用的锁)默认是可重入锁
- synchronized的重入实现机理
- 显式锁也有ReentrantLock这样的可重入锁
- 二、lock/unlock配合可重入锁进行AQS源码分析讲解
- 三、思考,上述可重入锁计数问题,redis哪个数据类型可以替代?
- 1、涉及到可重入锁,原来redis中string类型就无法满足要求,因为没法记录加锁几次,也就没法解锁
- 2、需要用到hash类型作为可重入锁:
- 3、案例命令:
- 4、小总结 太帅了!
- 四、`思考+设计重点(一横一纵)`
- 五、lua脚本
- 1、redis命令过程分析:
- 2、加锁lua脚本lock
- V1.0版本
- V2.0版本
- V3.0版本
- 在redis中测试
- 3、解锁lua脚本unlock
- 设计思路:先确定这个锁是不是自己的 再去解锁 最后删除锁
- V1.0 V2.0加参数
- 测试
- 六、将上述lua脚本整合进入Java程序
- 1、v6.0不满足可重入性,需要重新修改为v7.0
- 2、初始版本
- 3、新建RedisDistributedLock类并实现JUC里的Lock接口
- 4、满足JUC里的AQS对lock锁的接口规范定义来进行实现落地代码
- 5、结合设计模式开发属于自己的redis分布式锁工具类
- a、在tryLock里实现结合lua脚本的加锁
- b、unlock
- c、v7.0调用锁
- 6、工厂模式引入
- v7.0版本问题说明
- 引入工厂模式v7.1代码 将分为工厂类、redis分布式锁、业务类三个讲解
- 工厂类 相当于spring里在controller里的注入的service
- redis分布式锁 基本不变,但是在业务类中不再是直接调用,而是通过工厂类来间接调用
- 业务类,通过spring的注入工厂类,再调用对应分布式锁
- 七、测试可重入性
- 1、代码
- 2、结果 有错误 原因是两次进入锁时,生成的uuid不一致
- 3、脑图
- 4、解决
- 原因:是因为在设计redis锁时,每次调用都会new一个uuid。
- `解决方法`:在工厂类直接new,这样保证了同一次调用使用的一个uuid
前言
上一篇链接: 【redis】redis分布式锁(一)手写分布式锁1.0~6.0
一、可重入锁(又名递归锁)
1、说明:
2、分开解释:
3、可重入锁的种类
隐式锁(即synchronized关键字使用的锁)默认是可重入锁
synchronized的重入实现机理
显式锁也有ReentrantLock这样的可重入锁
结论:
二、lock/unlock配合可重入锁进行AQS源码分析讲解
三、思考,上述可重入锁计数问题,redis哪个数据类型可以替代?
1、涉及到可重入锁,原来redis中string类型就无法满足要求,因为没法记录加锁几次,也就没法解锁
2、需要用到hash类型作为可重入锁:
3、案例命令:
4、小总结 太帅了!
四、思考+设计重点(一横一纵)
五、lua脚本
1、redis命令过程分析:
2、加锁lua脚本lock
下边将使用lua脚本的方式,把可重入锁的案例语句原子化
V1.0版本
蓝色部分是重复的,可以合并
V2.0版本
redis中,hincrby是具有hset的功能的,所以可以将条件合并
V3.0版本
换成对应的参数
在redis中测试
3、解锁lua脚本unlock
设计思路:先确定这个锁是不是自己的 再去解锁 最后删除锁
V1.0 V2.0加参数
测试
六、将上述lua脚本整合进入Java程序
对外不再暴露加解锁的代码,直接封装成可执行方法
1、v6.0不满足可重入性,需要重新修改为v7.0
需要将加解锁剥离出来, 封装成可执行方法
2、初始版本
3、新建RedisDistributedLock类并实现JUC里的Lock接口
4、满足JUC里的AQS对lock锁的接口规范定义来进行实现落地代码
5、结合设计模式开发属于自己的redis分布式锁工具类
a、在tryLock里实现结合lua脚本的加锁
b、unlock
c、v7.0调用锁
6、工厂模式引入
v7.0版本问题说明
引入工厂模式v7.1代码 将分为工厂类、redis分布式锁、业务类三个讲解
工厂类 相当于spring里在controller里的注入的service
redis分布式锁 基本不变,但是在业务类中不再是直接调用,而是通过工厂类来间接调用
业务类,通过spring的注入工厂类,再调用对应分布式锁
七、测试可重入性
1、代码