手表网站海马300米潜水表,分析苏宁易购网站内容建设,谷歌paypal下载,互联网营销 网站 推荐Redisson主要解决一下问题
重入问题#xff1a;重入问题是指 获得锁的线程可以再次进入到相同的锁的代码块中#xff0c;可重入锁的意义在于防止死锁#xff0c;比如HashTable这样的代码中#xff0c;他的方法都是使用synchronized修饰的#xff0c;假如他在一个方法内重入问题是指 获得锁的线程可以再次进入到相同的锁的代码块中可重入锁的意义在于防止死锁比如HashTable这样的代码中他的方法都是使用synchronized修饰的假如他在一个方法内调用另一个方法那么此时如果是不可重入的不就死锁了吗所以可重入锁他的主要意义是防止死锁我们的synchronized和Lock锁都是可重入的。不可重试是指目前的分布式只能尝试一次我们认为合理的情况是当线程在获得锁失败后他应该能再次尝试获得锁。超时释放我们在加锁时增加了过期时间这样的我们可以防止死锁但是如果卡顿的时间超长虽然我们采用了lua表达式防止删锁的时候误删别人的锁但是毕竟没有锁住有安全隐患主从一致性如果Redis提供了主从集群当我们向集群写数据时主机需要异步的将数据同步给从机而万一在同步过去之前主机宕机了就会出现死锁问题。
一、分析可重入
1.原理
在Lock锁中他是借助于底层的一个voaltile的一个state变量来记录重入的状态的比如当前没有人持有这把锁那么state0假如有人持有这把锁那么state1如果持有这把锁的人再次持有这把锁那么state就会1 如果是对于synchronized而言他在c语言代码中会有一个count原理和state类似也是重入一次就加一释放一次就-1 直到减少成0 时表示当前这把锁没有被人持有。
在redission中也支持可重入锁
在分布式锁中他采用hash结构用来存储锁其中大key表示表示这把锁是否存在用小key表示当前这把锁被哪个线程持有所以接下来我们一起分析一下当前的这个lua表达式
2、获取锁源码
我们点进去Redisson获取锁的源码 可以发现如下代码 也就是下面的代码
-- 判断是否存在
if ((redis.call(exists, KEYS[1]) 0)-- 存在判断是否是自己的锁 or (redis.call(hexists, KEYS[1], ARGV[2]) 1)) then-- 不存在获取锁或者是自己的锁次数加1redis.call(hincrby, KEYS[1], ARGV[2], 1);-- 设置过期时间redis.call(pexpire, KEYS[1], ARGV[1]);-- 返回nilreturn nil;
end ;
-- 返回剩余过期时间
return redis.call(pttl, KEYS[1]);
1.这个地方一共有3个参数3 KEYS[1] 锁名称 ARGV[1] 锁失效时间 ARGV[2] id : threadId; 锁的小key exists: 判断数据是否存在 name是lock是否存在,如果0就表示当前这把锁不存在
redis.call(hincrby, KEYS[1], ARGV[2], 1);
直接获取锁并且计数器置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即为当前这把锁的失效时间
3、释放锁源码
-- 判断锁是否存在
if (redis.call(hexists, KEYS[1], ARGV[3]) 0) thenreturn nil;
end;-- 存在计数器-1
local counter redis.call(hincrby, KEYS[1], ARGV[3], -1);-- 如果计数器大于0则设置过期时间
if (counter 0) thenredis.call(pexpire, KEYS[1], ARGV[2]);return 0;
else-- 否则释放锁redis.call(del, KEYS[1]);-- 同时发布一个消息到指定channel通知锁已经释放redis.call(publish, KEYS[2], ARGV[1]);return 1;
end;return nil;
首先判断锁是否存在存在则计数器-1如果计数器大于0则刷新过期时间否则释放锁同时发布消息通知已释放锁
4、流程图
整个流程也就是这个流程图 二、分析解决不可重试