首页 > 其他 > 详细

Redisson源码分析一

时间:2021-06-09 18:26:54      阅读:30      评论:0      收藏:0      [点我收藏+]

  我们先来看看通过RedissonLock类中的tryLockInnerAsync()方法来获取一个锁的逻辑。代码如下:

<T> RFuture<T> tryLockInnerAsync(long waitTime, long leaseTime, TimeUnit unit, long threadId, RedisStrictCommand<T> command) {
        return evalWriteAsync(getRawName(), LongCodec.INSTANCE, command,
                "if (redis.call(‘exists‘, KEYS[1]) == 0) then " +
                        "redis.call(‘hincrby‘, 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]);",
                Collections.singletonList(getRawName()), unit.toMillis(leaseTime), getLockName(threadId));
    }

  这样就比较容易看出,重点是一系列的 redis 命令。分析如下:

  结合上面的参数声明,我们可以知道,这里KEYS[1]就是getName(),ARGV[2]是getLockName(threadId)。

  假设前面获取锁时传的name是“abc”,假设调用的线程ID是Thread-1,假设成员变量UUID类型的id是6f0829ed-bfd3-4e6f-bba3-6f3d66cd176c。

  那么KEYS[1]=abc,ARGV[2]=6f0829ed-bfd3-4e6f-bba3-6f3d66cd176c:Thread-1。

  因此,这段脚本的意思是

  1、判断有没有一个叫“abc”的key

  2、如果没有,则在其下设置一个字段为“6f0829ed-bfd3-4e6f-bba3-6f3d66cd176c:Thread-1”,值为“1”的键值对 ,并设置它的过期时间

  3、如果存在,则进一步判断“6f0829ed-bfd3-4e6f-bba3-6f3d66cd176c:Thread-1”是否存在,若存在,则其值加1,并重新设置过期时间

  4、返回“abc”的生存时间(毫秒)

  这里用的数据结构是hash,hash的结构是: key  字段1  值1 字段2  值2  。。。

  用在锁这个场景下,key就表示锁的名称,也可以理解为临界资源,字段就表示当前获得锁的线程。所有竞争这把锁的线程都要判断在这个key下有没有自己线程的字段,如果没有则不能获得锁,如果有,则相当于重入,字段值加1(次数)。

Redisson源码分析一

原文:https://www.cnblogs.com/rainbow2021/p/14866721.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!