当前位置:网站首页>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。
边栏推荐
- Version 2.0 de tapdata, Open Source Live Data Platform est maintenant disponible
- Grey correlation analysis link (portal) matlab
- 城市土地利用分布数据/城市功能区划分布数据/城市poi感兴趣点/植被类型分布
- [target tracking] |dimp: learning discriminative model prediction for tracking
- qt--将程序打包--不要安装qt-可以直接运行
- Codeforces Round #633 (Div. 2) B. Sorted Adjacent Differences
- How does Matplotlib generate multiple pictures in turn & only save these pictures without displaying them in the compiler
- How to make the conductive slip ring signal better
- 快手小程序担保支付php源码封装
- C语言-Cmake-CMakeLists.txt教程
猜你喜欢
QT--创建QT程序
SQLite3 data storage location created by Android
碳刷滑环在发电机中的作用
C语言-Cmake-CMakeLists.txt教程
Version 2.0 of tapdata, the open source live data platform, has been released
From starfish OS' continued deflationary consumption of SFO, the value of SFO in the long run
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(静态库,动态库)使用
The persistence mode of redis - RDB and AOF persistence mechanisms
PB9.0 insert OLE control error repair tool
随机推荐
Codeforces Round #649 (Div. 2)——A. XXXXX
从Starfish OS持续对SFO的通缩消耗,长远看SFO的价值
qt--將程序打包--不要安裝qt-可以直接運行
QT build with built-in application framework -- Hello World -- use min GW 32bit
Redux usage
The difference between distribution function and probability density function of random variables
Usage of xcolor color in latex
qt-使用自带的应用框架建立--hello world--使用min GW 32bit
What kind of MES system is a good system
AttributeError: ‘str‘ object has no attribute ‘strftime‘
从Starfish OS持续对SFO的通缩消耗,长远看SFO的价值
Remote Sensing投稿经验分享
静态路由配置全面详解,静态路由快速入门指南
Understanding of prior probability, posterior probability and Bayesian formula
剑指 Offer II 041. 滑动窗口的平均值
正则表达式
给刚入门或者准备转行网络工程师的朋友一些建议
Coordinate conversion of one-dimensional array and two-dimensional matrix (storage of matrix)
Get familiar with XML parsing quickly
【目标跟踪】|atom