NO.1

前言

NO.2

redisson RedLock实现

Config config = new Config();config.useClusterServers().setScanInterval(2000).addNodeAddress("redis://192.168.1.17:6379");RedissonClient client = Redisson.create(config);RLock lock1 = client.getLock("lock1");RLock lock2 = client.getLock("lock2");RLock lock3 = client.getLock("lock3");RedissonRedLock lock = new RedissonRedLock(lock1, lock2, lock3);lock.lock();lock.unlock();
声明了多个锁的客户端,有点像前面我们学习的RedissonMultiLock
声明了一个RedissonRedLock对象来管理锁
使用lock unlock方法来进行加锁解锁操作
// RedissonMultiLock.class@Overridepublic boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {long newLeaseTime = -1;if (leaseTime != -1) {if (waitTime == -1) {newLeaseTime = unit.toMillis(leaseTime);} else {newLeaseTime = unit.toMillis(waitTime)*2;}}long time = System.currentTimeMillis();long remainTime = -1;if (waitTime != -1) {remainTime = unit.toMillis(waitTime);}long lockWaitTime = calcLockWaitTime(remainTime);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 == -1 && leaseTime == -1) {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 {if (locks.size() - acquiredLocks.size() == failedLocksLimit()) {break;}if (failedLocksLimit == 0) {unlockInner(acquiredLocks);if (waitTime == -1) {return false;}failedLocksLimit = failedLocksLimit();acquiredLocks.clear();// reset iteratorwhile (iterator.hasPrevious()) {iterator.previous();}} else {failedLocksLimit--;}}if (remainTime != -1) {remainTime -= System.currentTimeMillis() - time;time = System.currentTimeMillis();if (remainTime <= 0) {unlockInner(acquiredLocks);return false;}}}if (leaseTime != -1) {acquiredLocks.stream().map(l -> (RedissonLock) l).map(l -> l.expireAsync(unit.toMillis(leaseTime), TimeUnit.MILLISECONDS)).forEach(f -> f.syncUninterruptibly());}return true;}// RedissonRedLock重写的方法@Overrideprotected int failedLocksLimit() {return locks.size() - minLocksAmount(locks);}protected int minLocksAmount(final List<RLock> locks) {return locks.size()/2 + 1;}@Overrideprotected long calcLockWaitTime(long remainTime) {return Math.max(remainTime / locks.size(), 1);}
查看RedissonRedLock的代码,我们发现他是RedissonMultiLock的子类,并且重写了failedLocksLimit()等一系列方法
failedLocksLimit方法就是表明我允许加锁失败的边界值
所以这个原理就是很简单了,和我们上面猜测的差不多
遍历锁集合,对每个锁都尝试在规定时间内加锁,如果成功,记录一下锁对象,加锁失败,则判断失败的个数是否达到边界值
未达到边界值,那么尝试获取下一把锁,只要失败的个数在边界值内,那么就加锁成功了
达到边界值,那么释放当前获取的所有锁,进行下一轮的尝试,直到成功加锁(过半机制)
NO.3

总结


点个在看你最好看
文章转载自程序猿西蒙,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




