Java项目——黑马点评(优惠券秒杀5之分布式锁)

分布式锁

基本原理

定义:分布式锁:满足分布式系统或集群模式下多进程可见并且互斥的锁。
特点:
在这里插入图片描述

不同实现方式对比

在这里插入图片描述

实现分布式锁时需要实现的两个基本方法————获取、释放
在这里插入图片描述
更改后使得语句具有原子性后——

SET lock thread1 NX EX 10

在这里插入图片描述
最后还要考虑锁的阻塞与非阻塞问题——这里我们采用非阻塞式锁(即获取失败后不等待直接返回失败)
详见Java基础——线程

以下则是完整的流程与方法——
在这里插入图片描述

一、基于setnx的分布式锁

(一)基于Redis实现分布式锁初级版本

需求: 定义一个类,实现下面接口,利用Redis实现分布式锁功能。

在这里插入图片描述

实现类——SImpleRedisTemplate.java

在这里插入图片描述
实现类详解——
流程图——
在这里插入图片描述

获取锁——
在这里插入图片描述
释放锁——
在这里插入图片描述

测试——VoucherOrderServicelmpl.java

在这里插入图片描述
同时用try—finally块包装起来——
有关try——finally知识点请点击这里
在这里插入图片描述
同样的启动两台tomcat模拟两台服务器,结果如下——
(同样确保在POSTman中使用同一用户发请求)

Redis键值对——
在这里插入图片描述

后台数据——
在这里插入图片描述
以上显示分布式锁成功运作!

(二)基于setnx的分布式锁可能出现的问题及解决方案

1、Redis分布式锁误删问题

引出——

归根结底安全问题在于(线程1)在释放锁的时候把别人的锁(线程2)
给删了
在这里插入图片描述

在这里插入图片描述

解决方案——

获取锁时存入的线程ID,在释放锁时进行对比即可
获取线程ID——
在这里插入图片描述
在这里插入图片描述

流程图重梳理——

在这里插入图片描述

代码修改——

在这里插入图片描述

总结——

在这里插入图片描述

2、分布式锁原子问题引发的误删问题

问题引出——

因为上面的流程判断锁与释放锁不在同一时刻,在这中间由于JVM的垃圾回收策略等会导致代码执行阻塞,也许又会有执行时间大于EX时间的情况发生,就又出现了上面的多线程并发安全问题。

解决方法——

归根结底是在于判断锁与释放锁不在同一时刻,让其一同执行就好(具有原子性就好)。
在这里插入图片描述

lua脚本——保证原子性

在这里插入图片描述
lua测试如下——
在这里插入图片描述

——含参数脚本语言
在这里插入图片描述

用Java语言实现脚本lua

RedisTemplate调用Lua脚本的API如下——

在这里插入图片描述
——业务流程
在这里插入图片描述

业务代码——

在这里插入图片描述

在这里插入图片描述

前后对比——

在这里插入图片描述

(三)基于setnx的分布式锁总结

在这里插入图片描述

二、基于Redisson的分布式锁

——引出,基于setnx分布式锁依然存在的的问题

在之前实现的锁已经能够满足大多数的场景,但是还有可以提升的空间。如下——在这里插入图片描述
有Redisson成熟框架下的支持——
Redisson——在Redis基础下实现的分布式工具集合**(分布式锁是它的子集)**

——以后凡是用到分布式锁时直接用这个开源框架就好

在这里插入图片描述

Redisson使用——

1、引入依赖
2、配置
3、使用即可
在这里插入图片描述
在这里插入图片描述

代码

配置文件RedissonConfig.java
在这里插入图片描述
业务类——VoucherOrderServicelmpl.java在这里插入图片描述在这里插入图片描述

(一)Redisson解决setnx不可重入锁的问题

Redisson可重入锁原理

有关详细的可重入机制请点击这里

在这里插入图片描述

获取锁逻辑lua——

在这里插入图片描述

释放锁逻辑lua——

在这里插入图片描述

在这里插入图片描述
获取锁系数为2——
在这里插入图片描述

退出后重入次数变为1——
在这里插入图片描述

debug——trylock源码

在这里插入图片描述

(二)Redisson的锁重试和WatchDog机制

重温setnx的锁存在的问题——

在这里插入图片描述
上面解决了Redisson解决不可重入的问题,剩下的3个问题Redisson是如何解决的?接下来解析源码解决之——

(三)Redisson解决setnx的不可重试、超时释放问题

详细源码分析教程请点击这里
在这里插入图片描述
在这里插入图片描述

(四)Redisson获取锁与释放锁的流程和交互——

在这里插入图片描述

(五)总结——Redisson分布式锁原理(无主从一致性)

在这里插入图片描述

(六)Redisson解决setnx的主从一致性问题multiLock

集群模式下——

#主从节点
在这里插入图片描述

存在的问题——

万一主节点宕机后——会从从节点选主,就会出现主从不一致,线程安全问题。
在这里插入图片描述

锁失效后就会出现线程安全问题——

在这里插入图片描述

Redisson的解决方案——multiLock

——多个节点都是主节点,必须全部主节点的锁都获取才能获取成功

在这里插入图片描述

——或者想要更高可用,再在此基础上加主从节点也可

在这里插入图片描述

三、分布式锁的总结

总共讲了三种锁,层层递进——
在这里插入图片描述

四、剩余问题

当前项目由于使用了大量的分布式锁与数据库的大量交互,虽然保证了一致性,但也造成了性能上的一些缺失。同时由于业务流程是串行的,在一个线程里面执行。解耦性能不好。
接下来就讲解如何在性能上提升——Java项目——黑马点评(优惠券秒杀6之优化秒杀)

  • 8
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值