通过redissonClient.getMultiLock(lock1, lock2, lock3...);
将多个锁放在一个list集合里,将来获取锁的时候需要遍历集合里的每一个锁,只有每个redis结点都获取锁成功,才会返回成功。
public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {
long newLeaseTime = -1L;
if (leaseTime != -1L) {
if (waitTime == -1L) {
newLeaseTime = unit.toMillis(leaseTime);
} else {
newLeaseTime = unit.toMillis(waitTime) * 2L;
}
}
long time = System.currentTimeMillis();
long remainTime = -1L;
if (waitTime != -1L) {
remainTime = unit.toMillis(waitTime);
}
long lockWaitTime = this.calcLockWaitTime(remainTime);
int failedLocksLimit = this.failedLocksLimit(); //失败的锁的限制 这个函数返回的是0
List<RLock> acquiredLocks = new ArrayList(this.locks.size());
ListIterator<RLock> iterator = this.locks.listIterator();
while(iterator.hasNext()) {
RLock lock = (RLock)iterator.next();
boolean lockAcquired;
try {
if (waitTime == -1L && leaseTime == -1L) {
lockAcquired = lock.tryLock(); // 如果等待时间是0,那么只尝试一次
} else {
long awaitTime = Math.min(lockWaitTime, remainTime);
lockAcquired = lock.tryLock(awaitTime, newLeaseTime, TimeUnit.MILLISECONDS); // 尝试锁需要重试
}
} catch (RedisResponseTimeoutException var21) {
this.unlockInner(Arrays.asList(lock));
lockAcquired = false;
} catch (Exception var22) {
lockAcquired = false;
}
if (lockAcquired) {
acquiredLocks.add(lock); // 获取锁成功,就把lock放在已经成功的锁的集合里
} else {
if (this.locks.size() - acquiredLocks.size() == this.failedLocksLimit()) { //所有的锁的数量-获取的锁的数量=0 才能break 换言之 只有把所有的锁都拿到了才能够break
break;
}
if (failedLocksLimit == 0) {
this.unlockInner(acquiredLocks);
if (waitTime == -1L) { // 没有等待时间 表示不想重试 则获取锁失败就直接返回失败
return false;
}
failedLocksLimit = this.failedLocksLimit();
acquiredLocks.clear(); // 有等待时间 想重试 那么就先把所有获取的锁先释放掉
while(iterator.hasPrevious()) {
iterator.previous(); // 将锁的迭代器指向第一把锁
}
} else {
--failedLocksLimit;
}
}
if (remainTime != -1L) {
remainTime -= System.currentTimeMillis() - time; // 将刚才获取锁的时间减去
time = System.currentTimeMillis();
if (remainTime <= 0L) { // 已经没有剩余时间了,那么就获取锁失败
this.unlockInner(acquiredLocks);// 将之前获取到的锁释放
return false;
}
}
}// 如果时间充足,就进行下一次迭代
if (leaseTime != -1L) { //如果我们传了锁的释放时间 那么在获取锁成功后 需要做的事情:
List<RFuture<Boolean>> futures = new ArrayList(acquiredLocks.size());
Iterator var24 = acquiredLocks.iterator();
while(var24.hasNext()) {
RLock rLock = (RLock)var24.next();
RFuture<Boolean> future = ((RedissonLock)rLock).expireAsync(unit.toMillis(leaseTime), TimeUnit.MILLISECONDS);
// 将获取到的所有锁的有效期重置,因为我们获取完第一把锁之后,获取的这个锁的有效期就开始计时了,所以获取锁成功后需要将所有的有效期进行重置
futures.add(future);
}
var24 = futures.iterator();
while(var24.hasNext()) {
RFuture<Boolean> rFuture = (RFuture)var24.next();
rFuture.syncUninterruptibly();
}
}
//为什么leaseTime = -1 就不需要将有效期进行重置。是因为当leaseTime == -1就会触发看门狗机制,所有锁的有效期都会自动重置
return true;
}