根据字节面试改编原创小说:分布式锁的隐私太多了系列之是谁偷偷释放了我的锁

310 阅读4分钟

引:趁大家午饭时间给大家整个文,下个馒头、下碗米饭、溜个小酒、开个胃~\

程序员的技术文章前序


青松成山
蓝天白云砌墙阳光穿透竹涧
洒在青石台上
萦绕残蝉杂与鸟鸣声
昨夜雨滴含蓄点落凉亭
避开城市的喧嚣与燥热
开始文字与自然的交织些许一杯绿茶才配这夏日份清爽~

可爱猪猪的周末又被悄然打开:
美好的周末,从一篇好文章开始!

分布式锁的隐私太多了系列之
第二弹:是谁偷偷释放你的锁?

剧情回顾

上一弹,揭秘了:Redis之死锁三进宫
回顾:根据字节面试改编原创小说:分布式锁的隐私太多了系列之死锁三进宫

我们循序找到了setnx+del的加锁、释放锁解决分布式环境下访问共享资源线程安全的三个漏洞:

    1. 代码异常导致死锁
      finally代码块释放锁保证异常也被触发锁释放\

    2. 进程意外终止导致死锁
      设置key的超时时间,迫使key最终也被释放,避免死锁\

    3. setnx与expire非原子性操作
      采用Redis 2.6.12配备的原子命令:SET lock 1 EX 10 NX。似完美解决! 
      经过三次优化,伪代码是这样的: \

// 获取锁并设置过期时间为30秒
boolean success = setnxAndsetExpire(key,30);
try{
   // 做一些不可描述的事情
   doSomeBeyondDescription();
}finally{
   // 释放锁
   del(key);
}

是不是就这样就大结局了?!  

Of Course,NO!!!

是谁偷偷释放了我们的锁?

引入多线程情况下,往往会增加程序开发与设计角度的复杂性。加锁操作也不例外。

两个线程或多个线程的之间通过共享资源通讯。我们通过下面纯手工绘图来看下会带来什么问题呢:

  • 线程1加锁(把门锁好)并设置超时时间30秒(给自己预估了30秒),开始做不可描述的事情并持续1分钟,(线程1比较持久😋),但是明显给自己预估的时间少了,在30秒的时候锁释放(门自动打开了)。
  • 线程2一直在等待拿锁,在30秒的时候,发现锁释放(门打开了,线程1还在里面做事情),结果线程2加锁(把门也锁好),也开始做一些不可描述的事情。
  • 线程1在2分30秒事情终于做完了,把锁释放了。(把门打开走了)
  • 线程3一直在等待拿锁,发现锁被释放。(门打开了,这时候线程2还在里面做事情
  • 线程3也开始做事情了...

场面一度尴尬,并失控了:

  • 30s的时候线程1和线程2在同时做事情    ----注:①
  • 2min3s的时候线程2和线程3在同时做事情 ----注:②

那是谁在偷偷的释放我们的锁?你肯定有了答案。
是线程1

如何保证锁不被别人偷偷释放?

今天这篇文章我们先说下问题②,关注我们公众号「面试怪圈」,我们下篇会继续侃问题①!

不知道你有没有解决思路呢?
揭秘啦!揭秘啦!
每个线程使用自己的专属token。 通过使用专属token每个线程只能释放自己加的锁🔐。 

伪代码是这样紫:

// 生成token
String token = UUID.random();

// 获取锁并设置过期时间为30秒,并给了一个专属token
boolean success = setnxAndsetExpire(key,token,30);
try{
   // 做一些不可描述的事情
   doSomeBeyondDescription();
}finally{
   // 释放锁,忽略==和equals的区别
   if(get(key) == token){
     del(key);
   }  
}

每个线程加的锁只能自己释放,线程1再也不会打开线程2的门了。

是不是Redis分布式锁就此无可挑剔了?


答案又是否定的?分布式环境和多线程的背景下,实在实在实在是太复杂了!

注①中线程1和线程2同时访问的共享代码块的问题并没有解决。

好了,饭点了,该上菜了!

根据字节面试改编原创小说:分布式锁的隐私太多了系列第三弹,下篇待续....

咱们在「面试怪圈」继续摆,我是可爱猪猪。  

走一个finally!

某猪说

某某: 猪你好危险呀?
猪猪: 为啥?
某某:你知道的太多了。
猪猪:😒 冷~  

猪猪不断学习使自己不愚钝。
猪猪将毕生的学习资料整理成了个人资源库:
有业界经典款面试题、基础教程、高阶教程、大厂面经、中间件实践、数据库原理、技术学习路线、思维导图...
太多了,写不下去了~

都看到这里了,过来瞅瞅这只奋斗的猪猪吧:
www.mianshiguaiquan.com 打开是这个样紫,是你钟爱的简约小小小卡片风格吧: