一,业务场景,秒杀系统

1,实现分布式锁

2,不能超卖

二,实现逻辑

1,synchronized,在抢购方法上加同步锁synchronized,弊端:只使用单机环境;很慢。只有所有逻辑执行完,下个人才能购买,把东西卖完耗时长

2,redis锁,在方法内部对商品加锁,解锁成功,继续执行购买操作,最后解锁。但是productId相同,不还是只用一个人能执行业务逻辑,其他用户只有等待吗?(暂不考虑为什么这样快)

三,加锁实现

3.1)如下,直接加锁,会导致两个问题

1,可能死锁,服务挂了,finally也没法释放

2,

3.2)针对上面的问题,直接加个过期时间不就行了,实际上是这样实现的,如下图

那中间这一坨代码实现什么功能?

1,设置过期时间,过期了,其他线程立即加锁执行购买

2,?

逻辑

1,线程1,加锁成功,返回true,下面代码不执行。这时候服务挂了,不还是死锁吗,没有过期时间?

假设起始时间为1000ms,即线程1进来时间

key:100

value:1000+100ms = 1100

线程1("100", "1100")

2,线程2,过了200ms,如果另外一个线程过来,当前时间1200

线程2("100", " 1300")1000+200+100 = 1300

currentValue:1100

当前系统时间:1000+200 = 1200 1100<1200,说明线程1过期了。

这时候业务可能没执行完(怎么办),且锁还没释放,在此获取时get/getAntSet时,发现锁过期了,才删除原来的锁,业务没执行完怎么办?锁已释放,是不是其他用户可以购买?是不是可以把值往大了设,确保业务逻辑执行完,finally释放锁(弊端:死锁了怎么办)(先不管)

3,如果线程1没过期,线程二返回false,加锁失败,不会执行购买逻辑,返回排队中...........

4,线程1过期了,线程2执行getAntSet,注意这里只有一个线程能执行成功(可能同时进来两个线程都执行到这里)

oldValue:1100

当前key value("100", "1300")

5,比较老值和当前值

老值:1100

currentValue:1100

相同,返回true,线程1失效时,线程2加锁成功(如果线程1逻辑没执行完,线程2也去执行业务逻辑,会不会导致超卖?)

6,然后呢,上面这些说明什么问题

实现了,如果前面线程过期,后面线程可以,立即加锁执行购买行为

然后呢,主要说明的是这种场景

线程1持有锁,并发情况下,线程2,线程3同时进入加锁方法,且value相同

线程1("100", "1100")

线程2,线程3("100", "1300")

如果当前时间1200,线程1过期,线程2设置了当前key value("100", "1300")

老值:1100

currentValue:1100,相同加锁成功

重要的是对于线程3来说,

currentValue:1100

oldValue:应该是线程2的值,1300

明显不相同,加锁失败,等待线程2执行。

巴拉巴拉差不多说完了,现在想想中间这坨代码干啥的?

1,过期了,其他人能够立刻购买成功

2,过期了,并发时,只要一个人能购买成功。如果不加这坨呢,直接加锁时加个过期时间,不过期时,其他线程过来返回false,有啥问题吗,又绕回去了。

想不通?

其他实现逻辑

1,判断是否被锁 isLock

2,是,不执行

3,否,加锁

4,释放锁

加锁方法返回Boolean,具体实现如下

redis分布式锁的复杂实现相关推荐

  1. redis分布式锁 在集群模式下如何实现_收藏慢慢看系列:简洁实用的Redis分布式锁用法...

    在微服务中很多情况下需要使用到分布式锁功能,而目前比较常见的方案是通过Redis来实现分布式锁,网上关于分布式锁的实现方式有很多,早期主要是基于Redisson等客户端,但在Spring Boot2. ...

  2. 快来学习Redis 分布式锁的背后原理

    以前在学校做小项目的时候,用到Redis,基本也只是用来当作缓存.可阿粉在工作中发现,Redis在生产中并不只是当作缓存这么简单.在阿粉接触到的项目中,Redis起到了一个分布式锁的作用,具体情况是这 ...

  3. Redis分布式锁使用不当,酿成一个重大事故,超卖了100瓶飞天茅台!!!

    点击关注公众号,Java干货及时送达 来源:juejin.cn/post/6854573212831842311 基于Redis使用分布式锁在当今已经不是什么新鲜事了. 本篇文章主要是基于我们实际项目 ...

  4. Redis 分布式锁使用不当,酿成一个重大事故,超卖了100瓶飞天茅台!!!

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 基于Redis使用分布式锁在当今已经不是什么新鲜事了. 本 ...

  5. 秒杀商品超卖事故:Redis分布式锁请慎用!

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:浪漫先生 来源:juejin.im/post/6854573 ...

  6. 记一次由Redis分布式锁造成的重大事故,避免以后踩坑!

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:浪漫先生 juejin.im/post/5f159cd8f2 ...

  7. 简单介绍redis分布式锁解决表单重复提交的问题

    在系统中,有些接口如果重复提交,可能会造成脏数据或者其他的严重的问题,所以我们一般会对与数据库有交互的接口进行重复处理.本文就详细的介绍一下redis分布式锁解决表单重复提交,感兴趣的可以了解一下 假 ...

  8. Redis 分布式锁没这么简单,网上大多数都有 bug

    Redis 分布式锁这个话题似乎烂大街了,不管你是面试还是工作,随处可见,「码哥」为啥还写? 因为看过很多文章没有将分布式锁的各种问题讲明白,所以准备写一篇,也当做自己的学习总结. 在进入正文之前,我 ...

  9. 深度剖析:Redis分布式锁到底安全吗?看完这篇文章彻底懂了!

    ‍‍‍‍‍‍‍‍‍‍‍‍阅读本文大约需要 20 分钟. 大家好,我是 Kaito. 这篇文章我想和你聊一聊,关于 Redis 分布式锁的「安全性」问题. Redis 分布式锁的话题,很多文章已经写烂了 ...

  10. SpringBoot + Redis 分布式锁:模拟抢单

    作者:神牛003 cnblogs.com/wangrudong003/p/10627539.html 本篇内容主要讲解的是redis分布式锁,这个在各大厂面试几乎都是必备的,下面结合模拟抢单的场景来使 ...

最新文章

  1. could not create cudnn handle: CUDNN_STATUS_INTERNAL_ERROR 错误的解决办法
  2. pbp 读取 mysql数据_SqlAlchemy 中操作数据库时session和scoped_session的区别(源码分析)...
  3. 基于python的FFT频率和振幅处理
  4. 一些常用的系统存储过程
  5. 我的设计模型之适配器模式
  6. Helm 3 完整教程(六):在模板中使用 Helm 函数
  7. Elasticsearch的javaAPI之facet,count,delete by query
  8. 统计python文件中的代码,注释,空白对应的行数
  9. html 强制占据一行,html – 如何强制内联div保持在同一行?
  10. Docker从理论到实践(二)------配置Docker镜像源加速器(部分使用效果已不太理想)
  11. 计算机ppt咋弄,ppt打不开怎么办?教您详细解决方法
  12. 计算机无法进bios,电脑进入不了bios界面怎么办_win7无法进入bios界面如何解决-系统城...
  13. 个人申请微信公众号步骤(含截图)
  14. 当你的Stream遇上Lambda就爱上了,超级无敌酷酷 - 第418篇
  15. 四旋翼无人机——导航、制导与控制的概念
  16. csp试题2:二十四点
  17. Socket error Event: 32 Error: 10053
  18. SecureCRTSecureFX(一):SecureCRT的介绍与下载安装
  19. Android项目源码分享
  20. 【玩转嵌入式屏幕显示】(四)TFT-LCD屏幕显示英文字符(ASCII)和字符串

热门文章

  1. Java第十二次作业:继承与抽象类解决工人与学生的问题,抽象类实例。抽象类作用——为多态创造了可能。抽象类的作用总结...
  2. iOS:NSDate的主要几种时间形式
  3. 改进:js修改iOS微信浏览器的title
  4. mycelipse中关于编码的配置
  5. 陆兆禧:此时此刻,非我莫属!
  6. c++学习笔记---指针
  7. C++实现获取汉字拼音首字母
  8. android按钮点击后闪退_iphone闪退是什么原因?
  9. Linux内核线程kernel thread详解--Linux进程的管理与调度(十)
  10. linux网络子系统分析(四)—— INET连接建立API分析之connect/accept