Redisson的问题,发了好多次,有没有人帮忙看看?
问题1
https://segmentfault.com/q/1010000044340018
问题2
https://segmentfault.com/q/1010000044380820
问题3
// 计算并返回队列中最后一个线程的ttl,并添加到队列和set集合中
// 获取队列中的最后一个元素
// lindex threadsQueueName -1
local lastThreadId = redis.call('lindex', KEYS[2], -1);
local ttl;
// 判断队列中最后一个元素不为空,且不等于uuid:threadId
if lastThreadId ~= false and lastThreadId ~= ARGV[2] then
// zscore redisson_lock_timeout:{lockName} lastThreadId - 当前时间
ttl = tonumber(redis.call('zscore', KEYS[3], lastThreadId)) - tonumber(ARGV[4]);
else
// 只有队列中的元素为空的
// pttl lockName
ttl = redis.call('pttl', KEYS[1]);
end;
// timeout = ttl + waitTime + currentTime
local timeout = ttl + tonumber(ARGV[3]) + tonumber(ARGV[4]);
// 设置set集合中的元素,会带上一个timeout作为score
// zadd redisson_lock_timeout:{lockName} timeout uuid:threadId
if redis.call('zadd', KEYS[3], timeout, ARGV[2]) == 1 then
// 将等待的线程设置到队列中
// rpush redisson_lock_queue:{lockName} uuid:threadId
redis.call('rpush', KEYS[2], ARGV[2]);
end;
// 返回ttl
return ttl;
这段脚本中 计算一个线程的 timeout作为score。
实际编码时
Redisson.create().getFairLock("test").tryLock(waitTime,leaseTime, TimeUnit.SECONDS);
为什么不直接使用当前时间戳+waitTime作为 score,而是使用了前一个节点的 ttl + waitTime + currentTime?
比如说我加锁等待超时时间为10秒,上面计算出来的ttl + waitTime 有可能已经是50秒了,
而当我索取锁失败的时候会返回ttl,然后本地线程阻塞 ttl的时间。
commandExecutor.getNow(subscribeFuture).getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS);
这不就相当于多阻塞了很长时间?
以上是 Redisson的问题,发了好多次,有没有人帮忙看看? 的全部内容, 来源链接: utcz.com/p/945419.html