为什么多个线程不可能同时抢到一把锁_HFL Redis_12_redis分布式锁的3种实现方式...

HotFrameLearning(简称 HFL) Redis_12_redis分布式锁的3种实现方式

-

一、大致介绍

```

1、昨天介绍完redis的数据结构后,有小伙伴让本人讲讲redis的分布式锁,因此才有了此篇的由来,只是把我的节奏提前了而已;

2、接下来我就通过几种方式介绍一下分布式锁的使用;

```

二、源码分享

2.1 获取redis锁且快速失败

af87122d39e37f31ed01cbc84c4f8ee4.png

图1 - 获取redis锁且快速失败

```

1、图1中,我们首先区分的是单机模式还是集群模式;

2、通过简单的 set 操作,但是要注意一点,set 时需要设置 expiryTimeMills 超时时间,而且设置key与设置expiryTimeMills需要是在一条原子语句里面,如果不是的话则会引起不必要的死锁问题;

3、至于为什么会引起死锁,假设 set key 与 set expiryTimeMills 是两条代码语句,当 set key 成功后,程序立马宕机了,那么这个 key 就没有失效时间,相当于永久有效,那么下次再次竞争获取该 key 时就永远都是失败的,因此要特别注意key与expiryTimeMills需要在同一条原子语句里面被执行;

4、当时又有人说,尝试一次就失败了,岂不是太不让调用方省心了,调用方想尝试多次还得自己写个代码玩玩,因此就有了下面尝试多次获取锁的操作;

```

2.2 尝试数次获取锁,获取不到则返回失败

1f61455efec665a9cac369060aca9dde.png

图2 - 尝试数次获取锁,获取不到则返回失败

```

1、图2中,同样我们首先区分的是单机模式还是集群模式;

2、通过在 tryLockFailFast 外面再套一层 while 循环处理,让入参多传入尝试次数retryTimes、尝试间隔时间retryIntervalMills 两个字段,即可满足多次尝试获取锁的诉求,这样调用方就能省心了;

3、虽然加锁是完事了,但是解锁呢,是不是直接删掉就完事了呢?请接着看~

```

2.3 释放redis锁且快速失败

25ecac233d407636132a6bc91a8aad71.png

图3 - 释放redis锁且快速失败

```

1、图3中,同样我们首先区分的是单机模式还是集群模式;

2、只是在解锁的时候,有点点不同,我们需要先看看我们解锁的key对应的内存值是不是我们当初加锁的那个入参值?

3、为什么要这么判断呢?原因就是假设A线程加锁了,但是A的任务还没有执行完,此时key超时过期了,然后B线程又成功抢到了该锁,但是当B前脚抢到锁后A后脚就执行完了任务准备释放锁,那么就会将B已经获取到的锁释放掉,这么一操作已不是把不该释放的释放了,最终都会导致相应业务功能执行出问题的;

4、因此才会在解锁的时候,看下锁对应的值是不是当初加锁的那个值,如果一致则删除,否则删除失败;

5、但是这么一连串的 get del 是两个命令语句,但是解锁的真实诉求需要保证原子性,因此我们就需要 redis 给我们提供的 lua 脚本原子性执行多个命令语句;

6、但是但是,说到这,又会有小伙伴会问,怕担心任务执行太久导致redis超时,有啥好的方式处理呢?接着看~

```

2.4 阻塞获取redisson锁

2ccf1350dab95ea91423565ccabf563b.png

图4 - 阻塞获取redisson锁

```

1、图4中,用的redisson框架版本号为 redisson-3.11.2.jar,具体maven坐标大家去中央仓库看吧;

2、大家会想,这个redisson和之前的 tryUnLockFailFast 的加锁有啥区别呢?不也是执行加锁么?

3、答案当然不一样,redisson 底层会有一个续命线程,每到过期时间的的1/3时就自动重新将过期时间置为入参的过期时间值,所以即使业务线程的任务执行很久,也不会因为锁自动过期一事而烦恼,岂不快哉;

```

2.5 redisson知识扩展

8890178bdb96f069ae76ec7c51f29b91.png

图5 - redisson知识扩展

```

1、图5中,我们稍微多看一眼 redisson 框架,然后我们会发现底层提供了很多的锁操作;

2、然而稍微再认真的同学仔细看看,会发现我们 JUC 有的类,这里都差不多实现了一番,可见 redisson 为分布式做了很多封装,方便调用方尽情的使用;

```

欢迎关注+点赞,您的肯定是对我最大的支持!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值