入口org.redisson.api.RedissonClient
@Resource
private RedissonClient redissonClient;
...
RLock rLock = redissonClient.getLock(lockName);
lockName就是保存到Redis里面的key
進入org.redisson.Redisson.getLock
@Override
public RLock getLock(String name) {
return new RedissonLock(commandExecutor, name);
}
進入org.redisson.RedissonLock
直接進行構(gòu)建方法里面的super(commandExecutor, name);
public RedissonBaseLock(CommandAsyncExecutor commandExecutor, String name) {
super(commandExecutor, name);
this.id = getServiceManager().getId();
this.internalLockLeaseTime = getServiceManager().getCfg().getLockWatchdogTimeout();
this.entryName = id + ":" + name;
}
org.redisson.connection.ServiceManager
:private final String id = UUID.randomUUID().toString();
- 這個
id
就是UUID
:this.id = getServiceManager().getId();
- 這個entryName通過UUID可以區(qū)分是哪個應用實例
- entryName+threadId可以區(qū)分哪個應用實例的哪個進程持有鎖
rLock.tryLock(60, TimeUnit.SECONDS);
嘗試獲取鎖文章來源:http://www.zghlxwxcb.cn/news/detail-501055.html
進入org.redisson.RedissonLock
<T> RFuture<T> tryLockInnerAsync(long waitTime, long leaseTime, TimeUnit unit, long threadId, RedisStrictCommand<T> command) {
return commandExecutor.syncedEval(getRawName(), LongCodec.INSTANCE, command,
"if ((redis.call('exists', KEYS[1]) == 0) " +
"or (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));
}
Collections.singletonList(getRawName())
,這個參數(shù)就是Redis的keyunit.toMillis(leaseTime)
,這個參數(shù)是Lua腳本的第1個參數(shù),即ARGV[1]
getLockName(threadId)
,這個參數(shù)是Lua腳本的第2個參數(shù),即ARGV[2]
- 這段Lua腳本的含義解析
(redis.call('exists', KEYS[1]) == 0)
,鎖不存在or (redis.call('hexists', KEYS[1], ARGV[2]) == 1))
,鎖存在,但是當前實例線程擁有該鎖- 以上兩種情況,均代表加鎖成功,則返回null
- 否則返回這個鎖對應的TTL時間
- 所以外層調(diào)用的地方是根據(jù)返回的ttl是否為null來判斷加鎖是否成功
Long ttl = tryAcquire(waitTime, leaseTime, unit, threadId);
// lock acquired
if (ttl == null) {
return true;
}
進入Lua腳本的第2個參數(shù)getLockName
protected String getLockName(long threadId) {
return id + ":" + threadId;
}
這個id就是上面提到的UUID,結(jié)合線程ID,可以判斷是哪個應用實例的哪個進程持有鎖文章來源地址http://www.zghlxwxcb.cn/news/detail-501055.html
到了這里,關(guān)于【Redisson】分布式鎖源碼分析如何實現(xiàn)多個應用實例互斥的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!