当前位置:网站首页>Redission源码解析
Redission源码解析
2022-07-08 00:28:00 【知知之之】
Redisson的加锁方法有两个,tryLock和lock,使用上的区别在于tryLock可以设置锁的过期时长leaseTime和等待时长waitTime,核心处理的逻辑都差不多
public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {
long time = unit.toMillis(waitTime);
long current = System.currentTimeMillis();
long threadId = Thread.currentThread().getId();
// 尝试获取锁,如果没取到锁,则返回锁的剩余超时时间
Long ttl = tryAcquire(waitTime, leaseTime, unit, threadId);
// lock acquired
// ttl为null,说明可以抢到锁了,返回true
if (ttl == null) {
return true;
}
// 如果waitTime已经超时了,就返回false,代表申请锁失败
time -= System.currentTimeMillis() - current;
if (time <= 0) {
acquireFailed(waitTime, unit, threadId);
return false;
}
current = System.currentTimeMillis();
/**
订阅锁释放事件,并通过 await 方法阻塞等待锁释放,有效的解决了无效的锁申请浪费资源的问题:
基于信息量,当锁被其它资源占用时,当前线程通过 Redis 的 channel 订阅锁的释放事件
一旦锁释放会发消息通知待等待的线程进行竞争.
*/
RFuture<RedissonLockEntry> subscribeFuture = subscribe(threadId);
if (!subscribeFuture.await(time, TimeUnit.MILLISECONDS)) {
if (!subscribeFuture.cancel(false)) {
subscribeFuture.onComplete((res, e) -> {
if (e == null) {
unsubscribe(subscribeFuture, threadId);
}
});
}
acquireFailed(waitTime, unit, threadId);
return false;
}
try {
//如果获取锁的耗时超过最大等待时间,加锁失败
time -= System.currentTimeMillis() - current;
if (time <= 0) {
acquireFailed(waitTime, unit, threadId);
return false;
}
//在最大等待时间内循环获取锁
while (true) {
long currentTime = System.currentTimeMillis();
ttl = tryAcquire(waitTime, leaseTime, unit, threadId);
// lock acquired
if (ttl == null) {
return true;
}
time -= System.currentTimeMillis() - currentTime;
if (time <= 0) {
acquireFailed(waitTime, unit, threadId);
return false;
}
// waiting for message
currentTime = System.currentTimeMillis();
// waiting for message,等待解锁消息
if (ttl >= 0 && ttl < time) {
subscribeFuture.getNow().getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS);
} else {
subscribeFuture.getNow().getLatch().tryAcquire(time, TimeUnit.MILLISECONDS);
}
time -= System.currentTimeMillis() - currentTime;
if (time <= 0) {
acquireFailed(waitTime, unit, threadId);
return false;
}
}
} finally {
//取消订阅消息
unsubscribe(subscribeFuture, threadId);
}
// return get(tryLockAsync(waitTime, leaseTime, unit));
}
需要特别注意的是,RedissonLock 同样没有解决 节点挂掉的时候,存在丢失锁的风险的问题。而现实情况是有一些场景无法容忍的,所以 Redisson 提供了实现了redlock算法的 RedissonRedLock,RedissonRedLock 真正解决了单点失败的问题,代价是需要额外的为 RedissonRedLock 搭建Redis环境。
所以,如果业务场景可以容忍这种小概率的错误,则推荐使用 RedissonLock, 如果无法容忍,则推荐使用 RedissonRedLock。
边栏推荐
- AttributeError: ‘str‘ object has no attribute ‘strftime‘
- 批次管控如何实现?MES系统给您答案
- How to realize batch control? MES system gives you the answer
- Euler Lagrange equation
- Codeforces Round #633 (Div. 2) B. Sorted Adjacent Differences
- 生态 | 湖仓一体的优选:GBase 8a MPP + XEOS
- QT--创建QT程序
- 如何让导电滑环信号更好
- 城市土地利用分布数据/城市功能区划分布数据/城市poi感兴趣点/植被类型分布
- How to fix the slip ring
猜你喜欢

C语言-Cmake-CMakeLists.txt教程

SQLite3 data storage location created by Android

C language - modularization -clion (static library, dynamic library) use

From starfish OS' continued deflationary consumption of SFO, the value of SFO in the long run

Why does the updated DNS record not take effect?

How to make enterprise recruitment QR code?

Sword finger offer II 041 Average value of sliding window

为什么更新了 DNS 记录不生效?

Remote Sensing投稿经验分享

Application of slip ring in direct drive motor rotor
随机推荐
Remote sensing contribution experience sharing
项目经理有必要考NPDP吗?我告诉你答案
About snake equation (2)
GBASE观察 | 数据泄露频发 信息系统安全应如何守护
Why did MySQL query not go to the index? This article will give you a comprehensive analysis
How to realize batch control? MES system gives you the answer
Sword finger offer II 041 Average value of sliding window
cv2读取视频-并保存图像或视频
由排行榜实时更新想到的数状数值
剑指 Offer II 041. 滑动窗口的平均值
The method of using thread in PowerBuilder
powerbuilder 中使用线程的方法
Partage d'expériences de contribution à distance
Usage of hydraulic rotary joint
The numerical value of the number of figures thought of by the real-time update of the ranking list
In depth analysis of ArrayList source code, from the most basic capacity expansion principle, to the magic iterator and fast fail mechanism, you have everything you want!!!
C语言-模块化-Clion(静态库,动态库)使用
Write a pure handwritten QT Hello World
Mat file usage
NPM internal split module