汉中做网站电话,关键字排名优化公司,张店网站制作设计公司,现在用什么工具做网站好5.3 分布式锁-redission可重入锁原理
在Lock锁中#xff0c;他是借助于底层的一个voaltile的一个state变量来记录重入的状态的#xff0c;比如当前没有人持有这把锁#xff0c;那么state0#xff0c;假如有人持有这把锁#xff0c;那么state1#xff0c;如果持有这把锁的…5.3 分布式锁-redission可重入锁原理
在Lock锁中他是借助于底层的一个voaltile的一个state变量来记录重入的状态的比如当前没有人持有这把锁那么state0假如有人持有这把锁那么state1如果持有这把锁的人再次持有这把锁那么state就会1 如果是对于synchronized而言他在c语言代码中会有一个count原理和state类似也是重入一次就加一释放一次就-1 直到减少成0 时表示当前这把锁没有被人持有。
在redission中我们的也支持支持可重入锁
在分布式锁中他采用hash结构用来存储锁其中大key表示表示这把锁是否存在用小key表示当前这把锁被哪个线程持有所以接下来我们一起分析一下当前的这个lua表达式
这个地方一共有3个参数
KEYS[1] 锁名称
ARGV[1] 锁失效时间
ARGV[2] id “:” threadId; 锁的小key
exists: 判断数据是否存在 name是lock是否存在,如果0就表示当前这把锁不存在
redis.call(‘hset’, KEYS[1], ARGV[2], 1);此时他就开始往redis里边去写数据 写成一个hash结构
Lock{
id “:” threadId : 1
}
如果当前这把锁存在则第一个条件不满足再判断
redis.call(‘hexists’, KEYS[1], ARGV[2]) 1
此时需要通过大key小key判断当前这把锁是否是属于自己的如果是自己的则进行
redis.call(‘hincrby’, KEYS[1], ARGV[2], 1)
将当前这个锁的value进行1 redis.call(‘pexpire’, KEYS[1], ARGV[1]); 然后再对其设置过期时间如果以上两个条件都不满足则表示当前这把锁抢锁失败最后返回pttl即为当前这把锁的失效时间
如果小伙帮们看了前边的源码 你会发现他会去判断当前这个方法的返回值是否为null如果是null则对应则前两个if对应的条件退出抢锁逻辑如果返回的不是null即走了第三个分支在源码处会进行while(true)的自旋抢锁。
if (redis.call(exists, KEYS[1]) 0) then redis.call(hset, KEYS[1], ARGV[2], 1); redis.call(pexpire, KEYS[1], ARGV[1]); return nil; end; if (redis.call(hexists, KEYS[1], ARGV[2]) 1) then redis.call(hincrby, KEYS[1], ARGV[2], 1); redis.call(pexpire, KEYS[1], ARGV[1]); return nil; end; return redis.call(pttl, KEYS[1]);