tryLock的三个重载中没有指定leaseTime时,如果获取到锁,默认自动释放时间为30秒,同时每10秒自动续期。

// 尝试立即获取锁的异步方法
private RFuture<Long> tryAcquireAsync(long waitTime, long leaseTime, TimeUnit unit, long threadId) {  
    RFuture<Long> ttlRemainingFuture;  
    // leaseTime在不指定时为-1,此时使用Reddison默认的internalLockLeaseTime(30秒)。
    // tryLockInnerAsync返回值:
    // 成功获取到锁:null的Future
    // 锁被其他线程占用:锁的ttl的Future
    if (leaseTime > 0) {  
        ttlRemainingFuture = tryLockInnerAsync(waitTime, leaseTime, unit, threadId, RedisCommands.EVAL_LONG);  
    } else {  
        ttlRemainingFuture = tryLockInnerAsync(waitTime, internalLockLeaseTime,  
                TimeUnit.MILLISECONDS, threadId, RedisCommands.EVAL_LONG);  
    }  
    CompletionStage<Long> s = handleNoSync(threadId, ttlRemainingFuture);  
    ttlRemainingFuture = new CompletableFutureWrapper<>(s);  
  
    CompletionStage<Long> f = ttlRemainingFuture.thenApply(ttlRemaining -> {  
        if (ttlRemaining == null) {  // 即获取到锁
            if (leaseTime > 0) {
                internalLockLeaseTime = unit.toMillis(leaseTime);  
            } else {  // 没有指定leaseTime,启动看门狗
                scheduleExpirationRenewal(threadId);  
            }  
        }  
        return ttlRemaining;
    });  
    return new CompletableFutureWrapper<>(f);  
}
 
// 看门狗启动入口
protected void scheduleExpirationRenewal(long threadId) {  
	// 如果当前线程的Entry不存在则创建,存在则使用旧的
    ExpirationEntry entry = new ExpirationEntry();  
    // EXPIRATION_RENEWAL_MAP是static final ConcurrentMap<String, ExpirationEntry>
    ExpirationEntry oldEntry = EXPIRATION_RENEWAL_MAP.putIfAbsent(getEntryName(), entry);  
    if (oldEntry != null) {  
        oldEntry.addThreadId(threadId);  // 重入次数加1
    } else {  
        entry.addThreadId(threadId);  // 重入次数加1
        try {  
            renewExpiration();  // 启动看门狗
        } finally {  
            if (Thread.currentThread().isInterrupted()) {  
                cancelExpirationRenewal(threadId);  
            }  
        }  
    }  
}
 
private void renewExpiration() {  
	// 检查业务是否已经完成
    ExpirationEntry ee = EXPIRATION_RENEWAL_MAP.get(getEntryName());  
    if (ee == null) {  
        return;  
    }  
    
    // 创建Netty延时任务
    Timeout task = getServiceManager().newTimeout(new TimerTask() {  
        @Override  
        public void run(Timeout timeout) throws Exception {  
            ExpirationEntry ent = EXPIRATION_RENEWAL_MAP.get(getEntryName());  
            if (ent == null) {  
                return;  
            }  
            Long threadId = ent.getFirstThreadId();  
            if (threadId == null) {  
                return;  
            }  
            // 续期脚本Future
            CompletionStage<Boolean> future = renewExpirationAsync(threadId);  
            future.whenComplete((res, e) -> { // res:续期是否成功,e:异常 
                if (e != null) {  // 有异常直接结束
                    log.error("Can't update lock {} expiration", getRawName(), e);  
                    EXPIRATION_RENEWAL_MAP.remove(getEntryName());  
                    return;  
                }  
                  
                if (res) {  
                    // 续期成功,递归
                    renewExpiration();  
                } else {  
	                // 续期失败,锁已经没了
                    cancelExpirationRenewal(null);  
                }  
            });  
        }  // internalLockLeaseTime默认为30秒,因此10秒续期一次
    }, internalLockLeaseTime / 3, TimeUnit.MILLISECONDS);  
      
    ee.setTimeout(task);  //将定时任务存到Entry中,unlock时取消
}
 
protected CompletionStage<Boolean> renewExpirationAsync(long threadId) {  
    return evalWriteAsync(getRawName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,  
            "if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " +  
                    "redis.call('pexpire', KEYS[1], ARGV[1]); " +  
                    "return 1; " +  
                    "end; " +  
                    "return 0;",  
            Collections.singletonList(getRawName()),  
            internalLockLeaseTime, getLockName(threadId));  
}