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
@Override
public 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 iterator
while (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重写的方法
@Override
protected int failedLocksLimit() {
return locks.size() - minLocksAmount(locks);
}
protected int minLocksAmount(final List<RLock> locks) {
return locks.size()/2 + 1;
}
@Override
protected long calcLockWaitTime(long remainTime) {
return Math.max(remainTime / locks.size(), 1);
}
复制
查看RedissonRedLock的代码,我们发现他是RedissonMultiLock的子类,并且重写了failedLocksLimit()等一系列方法
failedLocksLimit方法就是表明我允许加锁失败的边界值
所以这个原理就是很简单了,和我们上面猜测的差不多
遍历锁集合,对每个锁都尝试在规定时间内加锁,如果成功,记录一下锁对象,加锁失败,则判断失败的个数是否达到边界值
未达到边界值,那么尝试获取下一把锁,只要失败的个数在边界值内,那么就加锁成功了
达到边界值,那么释放当前获取的所有锁,进行下一轮的尝试,直到成功加锁(过半机制)
NO.3

总结


点个在看你最好看
文章转载自程序猿西蒙,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
redlock 分布式锁并不是集群模式,而是多个单实例redis服务组成分布式锁
1年前

评论
相关阅读
国产非关系型数据库 Eloqkv 初体验
JiekeXu
133次阅读
2025-04-10 23:51:35
融合Redis缓存的PostgreSQL高可用架构
梧桐
90次阅读
2025-04-08 06:35:40
Redis概要
听溪
38次阅读
2025-04-11 10:23:10
安装与配置Redis
鲁鲁
34次阅读
2025-04-11 10:26:10
Redis数据库——Cluster集群模式
编程Cookbook
29次阅读
2025-04-16 15:34:44
使用Jedis访问Redis数据库
怀念和想念
28次阅读
2025-04-11 15:08:30
Redis geo 实战:“附近的人”实现,打造社交的新维度
老王两点中
27次阅读
2025-04-11 09:02:30
Redis改协议内幕曝光!核心开发者亲述被“踢出局”,外部贡献者几乎全跑光了!
老鱼笔记
24次阅读
2025-04-17 10:41:56
Redis提供的持久化机制
luyingjun
24次阅读
2025-04-11 15:11:05
Redis
鲁鲁
22次阅读
2025-04-07 20:14:35