面试官再问Redis分布式锁如何续期?这篇文章甩 他一脸
一、真实案例
二、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一波操作,如下
- public class DemoMain{public static void main(String[] args)throwsException{
- Config config =newConfig();
- config.useSingleServer().setAddress("redis://127.0.0.1:6379");
- RedissonClient redisson = Redisson.create(config);
- RLock lock = redisson.getLock("anyLock");
- lock.lock();//lock.unlock();
- }
- }
create
从这里我们知道,internalLockLeaseTime和lockWatchdogTimeout这两个参数是相等的.
lockWatchdogTimeout默认值如下
- public class Config{private long lockWatchdogTimeout =30*1000;
- public long get LockWatchdogTimeout(){
- return lockWatchdogTimeout;
- }
- //省略无关代码
- }
从internalLockLeaseTime这个单词也可以看出,这个加的分布式锁的超时时间默认是30秒.但是还有一个问题,那就是这个看门狗,多久来延长一次有效期呢?我们往下看
lock
从我图中框起来的地方我们就知道了,获取锁成功就会开启一个定时任务,也就是watchdog,定时任务会定期检查去续期renewExpirationAsync(threadId).
这里定时用的是netty-common包中的HashedWheelTimer,肥朝公众号已经和各大搜索引擎建立了密切的合作关系,你只需要把这个类在任何搜索引擎一搜,都能知道相关API参数的意义.
从图中我们明白,该定时调度每次调用的时间差是internalLockLeaseTime / 3.也就10秒.
真相大白
通过源码分析我们知道,默认情况下,加锁的时间是30秒.如果加锁的业务没有执行完,那么到 30-10 = 20秒的时候,就会进行一次续期,把锁重置成30秒.那这个时候可能又有同学问了,那业务的机器万一宕机了呢?宕机了定时任务跑不了,就续不了期,那自然30秒之后锁就解开了呗.
本次给大家推荐一个免费的学习群,里面概括Java架构/分布式/微服务/docker/高性能高并发以及面试资源等。对Java架构感兴趣的程序猿,欢迎加入Q群:790047143,不管你是刚入行得还是大牛我都欢迎,还有大牛整理的一套高效率学习路线和教程与您免费分享,同时每天更新视频资料。
最后,祝大家早日学有所成。
最新文章
- xcode调试技巧
- ios UIView sizeToFit sizeThatFits
- chain.doFilter(req, resp)
- web语义化与h5新增标签
- 2014 New Year’s First Blog
- BZOJ 1821 部落划分
- Ubuntu 14.04 升级后 VPN 无法连接的问题
- hdu 2191 悼念512四川汶川大地震遇难者——如今宝,感恩生活
- hdu4704 Sum 2013 Multi-University Training Contest 10 数论题
- JavaEE中的MVC(一)Dao层彻底封装
- 单元测试与Mockito
- RabbitMQ “Hello world!”
- 055 kafka可靠性与高性能
- BASH if/while/until loop
- PHP工厂模式的使用场景,使用方法
- Python基本语法_强制数据类型转换
- Vue2.x整合百度地图JavaScript方案
- C++隐式转换与显式转换
- 把 Reative Native 47 版本集成到已有的 Native iOS 工程中
- (剑指Offer)面试题48:不能被继承的类
热门文章
- Excel自动语音点名-视频教学
- 认真分析mmap:是什么 为什么 怎么用(转)
- java中wait()和sleep()的区别;notify()和notifyall()区别
- [转]sql server 分页
- 【Python】 vscode使用code-runner 调试代码
- Classic BAdi and New BAdi
- echarts柱状图坐标文字显示不完整解决方式
- SQL中merge into用法
- C#中Control的Invoke和BeginInvoke是相对于支线线程
- SpringBoot小技巧:修改java可执行jar包内容