一、真实案例

二、Redis分布式锁的正确姿势

据肥朝了解,很多同学在用分布式锁时,都是直接百度搜索找一个Redis分布式锁工具类就直接用了.关键是该工具类中还充斥着很多System.out.println();等语句.其实Redis分布式锁比较正确的姿势是采用redisson这个客户端工具.具体介绍可以搜索最大的同性交友网站github.

三、如何回答

首先如果你之前用Redis的分布式锁的姿势正确,并且看过相应的官方文档的话,这个问题So easy.我们来看

坦白说,如果你英文棒棒哒那么看英文文档可能更好理解

By default lock watchdog timeout is 30 seconds and can be changed through Config.lockWatchdogTimeout setting.

但是你如果看的是中文文档

看门狗检查锁的超时时间默认是30秒

这句话从语文角度分析就是一个歧义句,他有两个意思

1.看门狗默认30秒去检查一次锁的超时时间

2.看们狗会去检查锁的超时时间,锁的时间时间默认是30秒

看到这里,我希望大家不要黑我的小学体育老师,虽然他和语文老师是同个人.语文不行,我们可以源码来凑!

四、源码分析

我们根据官方文档给出的例子,写了一个最简单的demo,例子根据上面截图中Ctr+C和Ctr+V一波操作,如下

  1. public class DemoMain{public static void main(String[] args)throwsException{
  2.  
  3. Config config =newConfig();
  4.  
  5. config.useSingleServer().setAddress("redis://127.0.0.1:6379");
  6.  
  7. RedissonClient redisson = Redisson.create(config);
  8.  
  9. RLock lock = redisson.getLock("anyLock");
  10.  
  11. lock.lock();//lock.unlock();
  12.  
  13. }
  14.  
  15. }

create

从这里我们知道,internalLockLeaseTime和lockWatchdogTimeout这两个参数是相等的.

lockWatchdogTimeout默认值如下

  1. public class Config{private long lockWatchdogTimeout =30*1000;
  2.  
  3. public long get LockWatchdogTimeout(){
  4.  
  5. return lockWatchdogTimeout;
  6.  
  7. }
  8.  
  9. //省略无关代码
  10.  
  11. }

从internalLockLeaseTime这个单词也可以看出,这个加的分布式锁的超时时间默认是30秒.但是还有一个问题,那就是这个看门狗,多久来延长一次有效期呢?我们往下看

lock

从我图中框起来的地方我们就知道了,获取锁成功就会开启一个定时任务,也就是watchdog,定时任务会定期检查去续期renewExpirationAsync(threadId).

这里定时用的是netty-common包中的HashedWheelTimer,肥朝公众号已经和各大搜索引擎建立了密切的合作关系,你只需要把这个类在任何搜索引擎一搜,都能知道相关API参数的意义.

从图中我们明白,该定时调度每次调用的时间差是internalLockLeaseTime / 3.也就10秒.

真相大白

通过源码分析我们知道,默认情况下,加锁的时间是30秒.如果加锁的业务没有执行完,那么到 30-10 = 20秒的时候,就会进行一次续期,把锁重置成30秒.那这个时候可能又有同学问了,那业务的机器万一宕机了呢?宕机了定时任务跑不了,就续不了期,那自然30秒之后锁就解开了呗.

本次给大家推荐一个免费的学习群,里面概括Java架构/分布式/微服务/docker/高性能高并发以及面试资源等。对Java架构感兴趣的程序猿,欢迎加入Q群:790047143,不管你是刚入行得还是大牛我都欢迎,还有大牛整理的一套高效率学习路线和教程与您免费分享,同时每天更新视频资料。
最后,祝大家早日学有所成。

最新文章

  1. xcode调试技巧
  2. ios UIView sizeToFit sizeThatFits
  3. chain.doFilter(req, resp)
  4. web语义化与h5新增标签
  5. 2014 New Year’s First Blog
  6. BZOJ 1821 部落划分
  7. Ubuntu 14.04 升级后 VPN 无法连接的问题
  8. hdu 2191 悼念512四川汶川大地震遇难者——如今宝,感恩生活
  9. hdu4704 Sum 2013 Multi-University Training Contest 10 数论题
  10. JavaEE中的MVC(一)Dao层彻底封装
  11. 单元测试与Mockito
  12. RabbitMQ “Hello world!”
  13. 055 kafka可靠性与高性能
  14. BASH if/while/until loop
  15. PHP工厂模式的使用场景,使用方法
  16. Python基本语法_强制数据类型转换
  17. Vue2.x整合百度地图JavaScript方案
  18. C++隐式转换与显式转换
  19. 把 Reative Native 47 版本集成到已有的 Native iOS 工程中
  20. (剑指Offer)面试题48:不能被继承的类

热门文章

  1. Excel自动语音点名-视频教学
  2. 认真分析mmap:是什么 为什么 怎么用(转)
  3. java中wait()和sleep()的区别;notify()和notifyall()区别
  4. [转]sql server 分页
  5. 【Python】 vscode使用code-runner 调试代码
  6. Classic BAdi and New BAdi
  7. echarts柱状图坐标文字显示不完整解决方式
  8. SQL中merge into用法
  9. C#中Control的Invoke和BeginInvoke是相对于支线线程
  10. SpringBoot小技巧:修改java可执行jar包内容