您现在的位置是:首页 >技术交流 >【redis】redis分布式锁(二)可重入锁+设计模式网站首页技术交流

【redis】redis分布式锁(二)可重入锁+设计模式

苗老八 2023-07-01 12:00:05
简介【redis】redis分布式锁(二)可重入锁+设计模式

【redis】redis分布式锁(二)可重入锁


文章目录


前言

上一篇链接: 【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、代码

在这里插入图片描述
在这里插入图片描述

2、结果 有错误 原因是两次进入锁时,生成的uuid不一致

在这里插入图片描述

3、脑图

在这里插入图片描述

4、解决

原因:是因为在设计redis锁时,每次调用都会new一个uuid。

解决方法:在工厂类直接new,这样保证了同一次调用使用的一个uuid

在这里插入图片描述


风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。