Redisson实现联锁的源码分析及机制

文章目录

  • 划重点(∩_∩)

public void lockInterruptibly(long leaseTime, TimeUnit unit) throws InterruptedException {
        long waitTime = -1;
        if (leaseTime == -1) {//未设置超时时间
            waitTime = 5;
            unit = TimeUnit.SECONDS;
        } else {
            waitTime = unit.toMillis(leaseTime);
            if (waitTime <= 2000) {//waitTime小于2000毫秒则赋值
                waitTime = 2000;
            } else if (waitTime <= 5000) {//赋予随机值
                waitTime = ThreadLocalRandom.current().nextLong(waitTime/2, waitTime);
            } else {//waitTime大于5000毫秒时赋值
                waitTime = ThreadLocalRandom.current().nextLong(5000, waitTime);
            }
            waitTime = unit.convert(waitTime, TimeUnit.MILLISECONDS);
        }
        
        while (true) {
            if (tryLock(waitTime, leaseTime, unit)) {
                return;
            }
        }
    }

下面的代码是联锁加锁逻辑的核心

public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {
        long newLeaseTime = -1;
        if (leaseTime != -1) {//设置了超时时间
            newLeaseTime = waitTime*2;
        }
        
        long time = System.currentTimeMillis();
        long remainTime = -1;//赋值保持时间
        if (waitTime != -1) {//设置了等待时间
            remainTime = unit.toMillis(waitTime);
        }
        int failedLocksLimit = failedLocksLimit();//failedLocksLimit()方法直接返回0
        List<RLock> lockedLocks = new ArrayList<RLock>(locks.size());
        //遍历我们加到到联锁中的所有锁
        for (ListIterator<RLock> iterator = locks.listIterator(); iterator.hasNext();) {
            RLock lock = iterator.next();
            boolean lockAcquired;
            try {
                if (waitTime == -1 && leaseTime == -1) {//未设置等待和超时时间
                    lockAcquired = lock.tryLock();
                } else {
                    long awaitTime = unit.convert(remainTime, TimeUnit.MILLISECONDS);
                    lockAcquired = lock.tryLock(awaitTime, newLeaseTime, unit);
                }
            } catch (Exception e) {
                lockAcquired = false;
            }
            
            if (lockAcquired) {//加锁成功
                lockedLocks.add(lock);
            } else {
                if (locks.size() - lockedLocks.size() == failedLocksLimit()) {//已全部加锁完成
                    break;
                }

                if (failedLocksLimit == 0) {
                    unlockInner(lockedLocks);
                    if (waitTime == -1 && leaseTime == -1) {
                        return false;
                    }
                    failedLocksLimit = failedLocksLimit();
                    lockedLocks.clear();
                    // reset iterator
                    while (iterator.hasPrevious()) {
                        iterator.previous();
                    }
                } else {
                    failedLocksLimit--;
                }
            }
            
            if (remainTime != -1) {//有设置保持时间
                remainTime -= (System.currentTimeMillis() - time);
                time = System.currentTimeMillis();
                if (remainTime <= 0) {
                    unlockInner(lockedLocks);
                    return false;
                }
            }
        }

        if (leaseTime != -1) {//有设置超时时间
            List<RFuture<Boolean>> futures = new ArrayList<RFuture<Boolean>>(lockedLocks.size());
            for (RLock rLock : lockedLocks) {
                RFuture<Boolean> future = rLock.expireAsync(unit.toMillis(leaseTime), TimeUnit.MILLISECONDS);
                futures.add(future);
            }
            
            for (RFuture<Boolean> rFuture : futures) {
                rFuture.syncUninterruptibly();
            }
        }
        
        return true;
    }

划重点(∩_∩)



本人程序媛一枚,因为离港澳较近,周末兼职港澳人肉代购。

欢迎各位大佬添加本人微信,还会经常有点赞活动送价值不菲的小礼品哦。

即使现在不需要代购,等以后有了女(男)朋友、有了宝宝就肯定会需要的喽。

动动手指头,扫码一下,就当是对本博文的支持嘛,也是对一个平凡、勤劳、勇敢、秀外慧中等等优点的程序媛莫大的支持哈。

你可能感兴趣的:(java技术,数据库)