tryLockInnerAsync
waitTime :指定等待时间
leaseTime:指定租约时间,即资源被持有的时间。
unit:时间单位
threadId:通常用于指定请求资源的线程的唯一标识符。
command: redis执行脚本命令:EVAL
<T> RFuture<T> tryLockInnerAsync(long waitTime, long leaseTime, TimeUnit unit, long threadId, RedisStrictCommand<T> command)
evalWriteAsync
key:通常用于指定Redis中的键
codec:这是一个编解码器对象,用于序列化和反序列化Redis的值。
evalCommandType:指定了要执行的Redis命令的类型
script: 通常用于指定要执行的Lua脚本。
keys:通常用于指定Lua脚本中要使用的键。 (该处是因为扩展性和兼容性,主要用于多个key同时操作)
params:传递任意数量的参数
protected <T> RFuture<T> evalWriteAsync(String key, Codec codec, RedisCommand<T> evalCommandType, String script, List<Object> keys, Object... params) {
script:
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));
KEYS[1]: keys参数
ARGV[2]: getLockName(threadId))
ARGV[1]: unit.toMillis(leaseTime)
"if (redis.call('exists', KEYS[1]) == 0) then " + //判断key 不存在
"redis.call('hincrby', KEYS[1], ARGV[2], 1); " + //hash中增加 key = ARGV[2] value =1
"redis.call('pexpire', KEYS[1], ARGV[1]); " + // 设置key 超时时间
"return nil; " +
"end; " +
"if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " + //如果存在
"redis.call('hincrby', KEYS[1], ARGV[2], 1); " +//将线程value加1
"redis.call('pexpire', KEYS[1], ARGV[1]); " +// 每次都将超时时间重新设置想要的值
"return nil; " +
"end; " +
"return redis.call('pttl', KEYS[1]);",
问题
如果单线程循环去锁,则锁的时间会重置,value会一直加1
对于多线程的常见下,一个线程id会不会一直被锁定