- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Redisson 分布式锁源码之公平锁加锁由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前言 。
默认的加锁逻辑是非公平的.
在加锁失败时,线程会进入 while 循环,一直尝试获得锁,这时候是多线程进行竞争。就是说谁抢到就是谁的.
Redisson 提供了公平锁机制,使用方式如下:
下面一起看下公平锁是如何实现的?
1公平锁 。
相信小伙伴们看过前面的文章,已经轻车熟路了,直接定位到源码方法:RedissonFairLock#tryLockInnerAsync.
好家伙,这一大块代码,我截图也截不完,咱们直接分析 lua 脚本.
PS:虽然咱不懂 lua,但是这一堆堆的 if else 咱们大概还是能看懂的.
因为 debug 发现 command == RedisCommands.EVAL_LONG,所以直接看下面一部分.
这么长,连呼好几声好家伙.
先来看看参数都有啥?
加锁队列和集合是含有大括号的字符串。{XXXX} 是指这个 key 仅使用 XXXX 用来计算 slot 的位置.
2Lua 脚本分析 。
上面的 lua 脚本是分为几块的,咱们分别从不同的角度看下上面代码的执行.
首次加锁(Thread1) 。
第一部分,因为是首次加锁,所以等待队列为空,直接 跳出循环。这一部分执行结束.
第二部分:
执行完这里就 return 了。所以后面几部分就暂时不看了.
相当于下面两个命令(整个 lua 脚本都是原子的!):
Thread2 加锁 。
当 Thread1 加锁完成之后,此时 Thread2 来加锁.
Thread2 可以是本实例其他线程,也可以是其他实例的线程.
第一部分,虽然锁被 Thread1 占用了,但是等待队列是空的,直接跳出循环.
第二部分,锁存在,直接跳过.
第三部分,线程是否持锁,没有持锁,直接跳过.
第四部分,线程是否在等待队列中,Thread2 才来加锁,不在里面,直接跳过.
Thread2 最后会来到这里:
zadd KEYS[3] timeout ARGV[2] 。
这里使用 zadd 命令分别放置的是,redisson_lock_timeout:{anyLock},超时时间戳(1624612689520),线程(UUID2:Thread2).
其中超时时间戳当分数,用来在有序集合中排序,表示加锁的顺序.
Thread3 加锁 。
Thread1 占有了锁,Thread2 在等待,此时线程 3 来了.
获取 firstThreadId2 此时队列是有线程的是 UUID2:Thread2.
判断 firstThreadId2 的分数(超时时间戳)是不是小于当前时间戳:
小于等于则说明超时了,移除 firstThreadId2,
大于,则会进入后续判断.
第2、3、四部分都不满足条件.
Thread3 最后也会来到这里:
3总结 。
本文主要总结了公平锁的加锁逻辑,这里涉及到比较多的 Redis 操作,做一下简要总结:
需要理解的就是这里会额外添加一个等待队列,以及有序集合.
原文链接:https://mp.weixin.qq.com/s/4EOWFNBIbGOKeW3r3YOKRQ 。
最后此篇关于Redisson 分布式锁源码之公平锁加锁的文章就讲到这里了,如果你想了解更多关于Redisson 分布式锁源码之公平锁加锁的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
给定一个主节点和多个启用 Sentinels 的副本节点,Redisson 配置为仅从副本节点读取,并启用循环负载均衡器和重试。在 Redisson 重试尝试的情况下,它会再次调用负载均衡器以确定新的
我正在使用 RMap 来存储 RLock。当我尝试从此映射中获取(key)时,它返回给我一个 RedissonReference 而不是 RLock 的实例。我无法将其转换为 RLock。我正在使用以
在解决 LiveObject 引发的异常时遇到问题,我尝试根据 Redisson 测试用例重现有问题的行为。 我重现问题的最少代码是这个测试用例(主要灵感来自 RedissonLiveObjectSe
什么是分布式锁?实现分布式锁的常用三种方式 在很多场景中,我们为了保证数据的最终一致性,需要很多的技术方案来支持,比如分布式事务、分布式锁等。那具体什么是分布式锁,分布式锁应用在哪些业务场景、如何来实
前言 默认的加锁逻辑是非公平的。 在加锁失败时,线程会进入 while 循环,一直尝试获得锁,这时候是多线程进行竞争。就是说谁抢到就是谁的。 Redisson 提供了公平锁机制,使用方式如
我需要保留添加到 Redis 中的 SET 的元素的顺序。为了做到这一点,我将 RSortedSet 与自定义比较器一起使用。 这里面临的问题是,与 RSetCache 不同,我无法使该 SET 中的
我正在为 redission 客户端编写一个适配器以在我们的应用程序中使用,我不确定在 Finalize block 中关闭客户端是否是一个好的设计。下面是代码。请告诉我 private static
我有一个 java 对象(ComponentType.java),我需要将其存储在 Redis 中。我使用 Redisson 作为客户端库。该对象有一个实例变量(ComponentType),该变量只
如果 key 大小非常大,是否有一种方法可以迭代扫描 key 而不会使 Redis 集群过载? Redis 原生支持这一点。 如果上述可行,那么我可以控制每次往返返回多少个 key 吗? 最佳答案 我
我正在为我的 Java 应用程序使用 Redisson。在他们的文档中说 redisson 在任何 redis 节点上创建对象。这是什么意思? 例如: If I do RSet l_campaign_
我正在使用单服务器模式配置redis服务器和端口,我在这里遗漏了什么吗? Config config = new Config(); config.useSingleServer().setAddre
我试图引用文档,但我仍然不清楚 CacheConfig 中 ttl 和 maxIdleTime 之间的区别。 Redisson 中的类。 任何人都可以解释一下吗? 最佳答案 maxIdleTime
我现在正在学习Redisson,我有一个例子如下: public class TestRedisson { public static void main(String[] args) {
Redisson的 getLock() 方法是否适合分布式用例,它与 getRedLock() 相比如何? Redisson(3.11.x)有几种实例化锁的方法: RedissonClient.get
在我当前的项目中,Redisson 用于使用 JsonJacksonCodec 缓存许多不同的类。这按预期工作,但我希望仅使用 MsgPack 序列化某个包中的类,而让其余部分按原样序列化。 根据我的
我们想使用redisson-hibernate项目https://github.com/redisson/redisson/tree/master/redisson-hibernate支持redis二
baeldung列出了 Redisson 作为 Redis 客户端的几个好处。所以我决定使用它。出于 POC 目的,我使用单节点实例,可能稍后会切换到其他实例。检查Redisson connectio
如果我想在 Redisson 中设置存储桶,是否需要通过合并 Redisson.getLock() 来防止竞争条件?或者 RBucket.set() 在内部执行此操作? 一般来说,除了应用程序需求之外
我正在使用 Redisson 库来管理 redis 中的数据,并具有以下 POJO(此处保留 get/set/constructor)。 @REntity Class A { @RId St
redisson 是否有合适的文档或最佳实践? 我正在使用 .getBlockingQueue(),它允许 offer() 和 put(),但我不知道是什么队列的容量是。我想将它设置为根据需要扩展,但
我是一名优秀的程序员,十分优秀!