当前位置:网站首页>[redisson] source code analysis of multilock

[redisson] source code analysis of multilock

2022-06-22 22:55:00 Roll a few you WOW

Keep creating , Accelerate growth ! This is my participation 「 Nuggets day new plan · 6 Yuegengwen challenge 」 Of the 25 God , Click to see the event details

Redisson Distributed lock support MultiLock Mechanism : You can combine multiple locks into one big lock , Apply for and release a large lock in a unified way .

Lock multiple resources at once , Then deal with the logic , Finally, release the lock corresponding to all resources at one time .

In the real world : Lock stock 、 Lock order 、 Lock the integral .

This may operate in the database , Use row lock .

Take a chestnut :

@Test
public void test() {
​
    RLock lock1 = redisson.getLock("lock1");
    RLock lock2 = redisson.getLock("lock2");
    RLock lock3 = redisson.getLock("lock3");
​
    RLock multiLock = redisson.getMultiLock(lock1, lock2, lock3);
​
    multiLock.lock();
    multiLock.unlock();
}

First look Get the lock RLock multiLock = redisson.getMultiLock(lock1, lock2, lock3);

actually : Just take an array to store these locks .

// RedissonMultiLock.java
//  Put it in a list 
final List<RLock> locks = new ArrayList<>();
    
public RedissonMultiLock(RLock... locks) {
    if (locks.length == 0) {
        throw new IllegalArgumentException("Lock objects are not defined");
    }
    this.locks.addAll(Arrays.asList(locks));
}

(1) Lock

// RedissonMultiLock.java
@Override
public void lock() {
    try {
        lockInterruptibly();
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}
​
@Override
public void lockInterruptibly() throws InterruptedException {
    lockInterruptibly(-1, null);
}
​
@Override
public void lockInterruptibly(long leaseTime, TimeUnit unit) throws InterruptedException {
    // 1.  Calculate the waiting time 
    //  Waiting time  =  Number of locks  * 1500, 3 Lock rule  4500
    long baseWaitTime = locks.size() * 1500;
    long waitTime = -1;
    if (leaseTime == -1) {
        waitTime = baseWaitTime;
    } else { //  Custom waiting time 
        leaseTime = unit.toMillis(leaseTime);
        waitTime = leaseTime;
        if (waitTime <= 2000) {
            waitTime = 2000;
        } else if (waitTime <= baseWaitTime) {
            waitTime = ThreadLocalRandom.current().nextLong(waitTime/2, waitTime);
        } else {
            waitTime = ThreadLocalRandom.current().nextLong(baseWaitTime, waitTime);
        }
    }
    
    // 2.  Wait for all locks to succeed 
    while (true) {
        if (tryLock(waitTime, leaseTime, TimeUnit.MILLISECONDS)) {
            return;
        }
    }
}

This process , It is mainly divided into two parts :

  1. Calculate the waiting time : Related to the number of locks ; 3 A lock , Waiting time = 3 * 1500 = 4500
  2. Try to apply all locks : Infinite loop , Until all locks are added successfully

Get into tryLock(), Look at its source code :

@Override
public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit)    throws InterruptedException {
    // 1.  Traversal attempts to lock each lock  
    //  As long as one lock fails to lock , Unlock the previous , Then lock it again 
    //  A bunch of logic , Don't let it be 
    {...}
​
    // 2.  A lock has a time limit , Asynchronous expiration check 
    {...}
​
    return true;
}

How long must it take to acquire all the locks , If it times out, it will try to acquire the lock again .

The use of each lock tryLock() Method , Specifies that when acquiring each individual lock , There will be a timeout exit time .

(2) Release the lock

@Override
public void unlock() {
    List<RFuture<Void>> futures = new ArrayList<>(locks.size());
​
    //  Asynchronous release lock 
    //  The release of the lock , For specific locks , It's not going to unfold here .
    for (RLock lock : locks) {
        futures.add(lock.unlockAsync());
    }
​
    //  Wait for all locks to release 
    for (RFuture<Void> future : futures) {
        future.syncUninterruptibly();
    }
}
原网站

版权声明
本文为[Roll a few you WOW]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/173/202206222042503553.html