前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redisson分布式锁----源码详解(三)

Redisson分布式锁----源码详解(三)

作者头像
用户9919783
发布2022-07-26 11:35:36
6040
发布2022-07-26 11:35:36
举报
文章被收录于专栏:后端从入门到精通

之前有两篇文章,已经介绍过redisson分布式的代码使用教程,上锁流程。

Redisson分布式锁流程详解(二)

Redisson分布式锁使用实例(一)

这篇文章主要详细解析redisson源码。Redis本身就能实现分布式锁,因为他是单线程,并且有天然的幂等性,互斥性,通过setNx也能加锁,处理好释放锁的逻辑即可,Redisson可以理解为redis的高级管理端。

Redisson有lock和tryLock两种上锁方法:

Lock:直接加锁,若锁被占用,则进入阻塞,一直等到锁被释放为止。

tryLock:返回true或false,可以设置获取锁的等待超时时间,若锁被其他线程获取,则在等待时间内一直尝试加锁,超过等待时间,则返回false,获取失败。

接下来看tryLock源码:

从源码我们可以看到,主要逻辑就是获取锁,判断其他线程是否获取锁,若获取了就重复尝试获取,然后期间有若干超时判断:

1、先是tryAcquire方法尝试获取锁,若其他线程未获取,则直接返回null,直接返回true加锁成功。

2、若其他线程获取了锁,则返回其他线程的获取锁时间。然后看自己当前锁是否超时,未超时则进入死循环继续尝试获取锁。

tryAcquire方法干嘛的呢? 上图就是在此方法里的代码,该方法里面主要和redis通信,用lua封装复杂的业务逻辑发给redis,若key没有上锁,则返回null,上锁了,则返回超时时间。

这个waiting for message 是干什么的呢?

waitTime和redis锁住的key的超时时间大小做比较,取二者中比较小的值,用java的Semaphore信号量tryAcquire方法来阻塞线程,Semaphore是由上面的代码subscribe方法控制的。

subscribe方法,它会进入到PublishSubscribe.java中,当前的线程ID添加到AsyncSemaphore,并且设置redis的监听器,这个监听器是通过redis的发布、订阅功能实现的, 一旦监听器收到redis发来的消息,就从中获取与当前thread相关的消息,如果是锁被释放的消息,就立马通过操作Semaphore来让刚才阻塞的地方释放

如果锁重入了怎么办呢,比如同一个线程,两次tryLock,怎么保证全部都能释放锁?

lua脚本有两个if,第一个if如果成立,则会加锁成功,因为现在已经是重入锁,第二次加锁了,所以第一个if判断肯定不成立,第二个if会获取当前客户端的ID,这时候会执行可重入锁的逻辑,对当前客户端累计加1。释放锁的时候如何释放呢,其实就是unlock,每次对统计的加锁数量减1,若为0了,则del myLock,在redis里删除这个key。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 后端从入门到精通 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档