接着我们看下lock()的具体实现
RedissonMultiLock实现原理 1public class RedissonMultiLock implements Lock {2
3 final List<RLock> locks = new ArrayList<RLock>();
4
5 public RedissonMultiLock(RLock... locks) {
6 if (locks.length == 0) {
7 throw new IllegalArgumentException("Lock objects are not defined");
8 }
9 this.locks.addAll(Arrays.asList(locks));
10 }
11
12 public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {
13 long newLeaseTime = -1;
14 if (leaseTime != -1) {
15 // 如果等待时间设置了,那么将等待时间 * 2
16 newLeaseTime = unit.toMillis(waitTime)*2;
17 }
18
19 // time为当前时间戳
20 long time = System.currentTimeMillis();
21 long remainTime = -1;
22 if (waitTime != -1) {
23 remainTime = unit.toMillis(waitTime);
24 }
25 // 计算锁的等待时间,RedLock中:如果remainTime=-1,那么lockWaitTime为1
26 long lockWaitTime = calcLockWaitTime(remainTime);
27
28 // RedLock中failedLocksLimit即为n/2 + 1
29 int failedLocksLimit = failedLocksLimit();
30 List<RLock> acquiredLocks = new ArrayList<RLock>(locks.size());
31 // 循环每个redis客户端,去获取锁
32 for (ListIterator<RLock> iterator = locks.listIterator(); iterator.hasNext();) {
33 RLock lock = iterator.next();
34 boolean lockAcquired;
35 try {
36 // 调用tryLock方法去获取锁,如果获取锁成功,则lockAcquired=true
37 if (waitTime == -1 && leaseTime == -1) {
38 lockAcquired = lock.tryLock();
39 } else {
40 long awaitTime = Math.min(lockWaitTime, remainTime);
41 lockAcquired = lock.tryLock(awaitTime, newLeaseTime, TimeUnit.MILLISECONDS);
42 }
43 } catch (Exception e) {
44 lockAcquired = false;
45 }
46
47 // 如果获取锁成功,将锁加入到list集合中
48 if (lockAcquired) {
49 acquiredLocks.add(lock);
50 } else {
51 // 如果获取锁失败,判断失败次数是否等于失败的限制次数
52 // 比如,3个redis客户端,最多只能失败1次
53 // 这里locks.size = 3, 3-x=1,说明只要成功了2次就可以直接break掉循环
54 if (locks.size() - acquiredLocks.size() == failedLocksLimit()) {
55 break;
56 }
57
58 // 如果最大失败次数等于0
59 if (failedLocksLimit == 0) {
60 // 释放所有的锁,RedLock加锁失败
61 unlockInner(acquiredLocks);
62 if (waitTime == -1 && leaseTime == -1) {
63 return false;
64 }
65 failedLocksLimit = failedLocksLimit();
66 acquiredLocks.clear();
67 // 重置迭代器 重试再次获取锁
68 while (iterator.hasPrevious()) {
69 iterator.previous();
70 }
71 } else {
72 // 失败的限制次数减一
73 // 比如3个redis实例,最大的限制次数是1,如果遍历第一个redis实例,失败了,那么failedLocksLimit会减成0
74 // 如果failedLocksLimit就会走上面的if逻辑,释放所有的锁,然后返回false
75 failedLocksLimit--;
76 }
77 }
78
79 if (remainTime != -1) {
80 remainTime -= (System.currentTimeMillis() - time);
81 time = System.currentTimeMillis();
82 if (remainTime <= 0) {
83 unlockInner(acquiredLocks);
84 return false;
85 }
86 }
87 }
88
89 if (leaseTime != -1) {
90 List<RFuture<Boolean>> futures = new ArrayList<RFuture<Boolean>>(acquiredLocks.size());
91 for (RLock rLock : acquiredLocks) {
92 RFuture<Boolean> future = rLock.expireAsync(unit.toMillis(leaseTime), TimeUnit.MILLISECONDS);
93 futures.add(future);
94 }
95
96 for (RFuture<Boolean> rFuture : futures) {
97 rFuture.syncUninterruptibly();
98 }
99 }
100
101 return true;
102 }
103}