03 RedissonMultiLock

redisson 基于 org.redisson:redisson-spring-data-27:3.27.2 版本

java 中,操作 redis 一般都会选择 redisson 框架, 我们需要了解常用功能的实现原理, 这次来介绍 RedissonMultiLock

使用方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
@Test
void testMultiLock() {
    RLock lock1 = redissonClient.getLock("lock1");
    RLock lock2 = redissonClient.getLock("lock2");
    RLock lock = redissonClient.getMultiLock(lock1, lock2);
    try {
        lock.lock();
        ThreadUtil.sleep(30, TimeUnit.SECONDS);
        System.out.println("xxx");
    } finally {
        lock.unlock();
    }
} 

在实际使用过程中,可能一次性获取多个锁, 那么你应该使用 RedissonMultiLock 来简化你的操作。

lock

源码位置: org.redisson.RedissonMultiLock#tryLock

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// lock 最终会调用 tryLock 方法
@Override
public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {
    ...
    int failedLocksLimit = failedLocksLimit();
    List<RLock> acquiredLocks = new ArrayList<>(locks.size());
    // 遍历获取每个锁
    for (ListIterator<RLock> iterator = locks.listIterator(); iterator.hasNext();) {
        RLock lock = iterator.next();
        boolean lockAcquired;
        try {
            if (waitTime <= 0 && leaseTime <= 0) {
                lockAcquired = lock.tryLock();
            } else {
                long awaitTime = Math.min(lockWaitTime, remainTime);
                // 尝试获取锁
                lockAcquired = lock.tryLock(awaitTime, newLeaseTime, TimeUnit.MILLISECONDS);
            }
        } catch (RedisResponseTimeoutException e) {
            unlockInner(Arrays.asList(lock));
            lockAcquired = false;
        } catch (Exception e) {
            lockAcquired = false;
        }
        
        if (lockAcquired) {
            // 获取锁成功
            acquiredLocks.add(lock);
        } else {
            // 判断容错次数, failedLocksLimit() 默认为 0
            if (locks.size() - acquiredLocks.size() == failedLocksLimit()) {
                break;
            }
            // 获取锁失败
            if (failedLocksLimit == 0) {
               // 释放之前的锁
                unlockInner(acquiredLocks);
                if (waitTime <= 0) {
                    return false;
                }
                failedLocksLimit = failedLocksLimit();
                acquiredLocks.clear();
                // reset iterator
                while (iterator.hasPrevious()) {
                    iterator.previous();
                }
            } else {
                failedLocksLimit--;
            }
        }
        ...
    }
    return true;
}

unlock

源码位置: org.redisson.RedissonMultiLock#unlock

1
2
3
4
5
@Override
public void unlock() {
    // 遍历每个锁,然后解锁
    locks.forEach(Lock::unlock);
}
0%