当前位置: 首页 > news >正文

redisson中的分布式锁

我的博客大纲

我的后端学习大纲


a.redisson概述:

  • 1.Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)
  • 2.redisson介绍官方文档地址:
  • 3.Redisson它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务
    • 包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, AtomicLong, CountDownLatch, Publish / Subscribe, Bloom filter, Remote service, Spring cache, Executor service, Live Object service, Scheduler service)
    • Redisson提供了使用Redis的最简单和最便捷的方法。
    • Redisson的宗旨是促进使用者对Redis的关注分离(Separation of Concern),从而让使用者能够将精力更集中地放在处理业务逻辑上。
      在这里插入图片描述

b.各分布式锁介绍:

b1.可重入锁(Reentrant Lock)
b1-1.概述:
  • 1.基于Redis的Redisson分布式可重入锁RLock Java对象实现了java.util.concurrent.locks.Lock接口。
  • 2.如果负责储存这个分布式锁的Redisson节点宕机以后,而且这个锁正好处于锁住的状态时,这个锁会出现锁死的状态。为了避免这种情况的发生,Redisson内部提供了一个监控锁的看门狗,它的作用是在Redisson实例被关闭前,不断的延长锁的有效期
  • 3.默认情况下,看门狗检查锁的超时时间是30秒钟,也可以通过修改Config.lockWatchdogTimeout来另行指定。
  • 4.RLock对象完全符合Java的Lock规范。也就是说只有拥有锁的进程才能解锁,其他进程解锁则会抛出IllegalMonitorStateException错误。
  • 5.另外Redisson还通过加锁的方法提供了leaseTime的参数来指定加锁的时间。超过这个时间后锁便自动解开了。
RLock lock = redisson.getLock("anyLock");
// 最常见的使用方法
lock.lock();// 加锁以后10秒钟自动解锁
// 无需调用unlock方法手动解锁
lock.lock(10, TimeUnit.SECONDS);// 尝试加锁,最多等待100秒,上锁以后10秒自动解锁
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {try {...} finally {lock.unlock();}
}
b1-2.编码实现:
  • 1.引入依赖
<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.11.2</version>
</dependency>
  • 2.添加配置
@Configuration
public class RedissonConfig {@Beanpublic RedissonClient redissonClient(){Config config = new Config();// 可以用"rediss://"来启用SSL连接config.useSingleServer().setAddress("redis://172.16.116.100:6379");return Redisson.create(config);}
}
  • 3.代码中使用
@Autowired
private RedissonClient redissonClient;public void checkAndLock() {// 加锁,获取锁失败重试RLock lock = this.redissonClient.getLock("lock");lock.lock();// 先查询库存是否充足Stock stock = this.stockMapper.selectById(1L);// 再减库存if (stock != null && stock.getCount() > 0){stock.setCount(stock.getCount() - 1);this.stockMapper.updateById(stock);}// 释放锁lock.unlock();
}
  • 4.压力测试:性能跟我们手写的区别不大。
    在这里插入图片描述
  • 5.数据库也没有问题
b2. 公平锁(Fair Lock)
  • 1.基于Redis的Redisson分布式可重入公平锁也是实现了java.util.concurrent.locks.Lock接口的一种RLock对象。
  • 2.同时还提供了异步(Async)、反射式(Reactive)和RxJava2标准的接口。
  • 3.它保证了当多个Redisson客户端线程同时请求加锁时,优先分配给先发出请求的线程。
  • 4.所有请求线程会在一个队列中排队,当某个线程出现宕机时,Redisson会等待5秒后继续下一个线程,也就是说如果前面有5个线程都处于等待状态,那么后面的线程会等待至少25秒。
RLock fairLock = redisson.getFairLock("anyLock");
// 最常见的使用方法
fairLock.lock();// 10秒钟以后自动解锁
// 无需调用unlock方法手动解锁
fairLock.lock(10, TimeUnit.SECONDS);// 尝试加锁,最多等待100秒,上锁以后10秒自动解锁
boolean res = fairLock.tryLock(100, 10, TimeUnit.SECONDS);
fairLock.unlock();
b3. 联锁(MultiLock)
  • 1.基于Redis的Redisson分布式联锁RedissonMultiLock对象可以将多个RLock对象关联为一个联锁,每个RLock对象实例可以来自于不同的Redisson实例。
RLock lock1 = redissonInstance1.getLock("lock1");
RLock lock2 = redissonInstance2.getLock("lock2");
RLock lock3 = redissonInstance3.getLock("lock3");RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3);
// 同时加锁:lock1 lock2 lock3
// 所有的锁都上锁成功才算成功。
lock.lock();
...
lock.unlock();
b4. 红锁(RedLock)
  • 1.基于Redis的Redisson红锁RedissonRedLock对象实现了Redlock介绍的加锁算法。
  • 2.该对象也可以用来将多个RLock对象关联为一个红锁,每个RLock对象实例可以来自于不同的Redisson实例。
RLock lock1 = redissonInstance1.getLock("lock1");
RLock lock2 = redissonInstance2.getLock("lock2");
RLock lock3 = redissonInstance3.getLock("lock3");
RedissonRedLock lock = new RedissonRedLock(lock1, lock2, lock3);
// 同时加锁:lock1 lock2 lock3
// 红锁在大部分节点上加锁成功就算成功。
lock.lock();
...
lock.unlock();
b5. 读写锁(ReadWriteLock)
b5-1.概述:
  • 1.基于Redis的Redisson分布式可重入读写锁RReadWriteLock Java对象实现了java.util.concurrent.locks.ReadWriteLock接口。
  • 2.其中读锁和写锁都继承了RLock接口。
  • 3.分布式可重入读写锁允许同时有多个读锁和一个写锁处于加锁状态。
b5-2.编码实现:
RReadWriteLock rwlock = redisson.getReadWriteLock("anyRWLock");
// 最常见的使用方法
rwlock.readLock().lock();
// 或
rwlock.writeLock().lock();
// 10秒钟以后自动解锁
// 无需调用unlock方法手动解锁
rwlock.readLock().lock(10, TimeUnit.SECONDS);
// 或
rwlock.writeLock().lock(10, TimeUnit.SECONDS);// 尝试加锁,最多等待100秒,上锁以后10秒自动解锁
boolean res = rwlock.readLock().tryLock(100, 10, TimeUnit.SECONDS);
// 或
boolean res = rwlock.writeLock().tryLock(100, 10, TimeUnit.SECONDS);
...
lock.unlock();

添加StockController方法:

@GetMapping("test/read")
public String testRead(){String msg = stockService.testRead();return "测试读";
}@GetMapping("test/write")
public String testWrite(){String msg = stockService.testWrite();return "测试写";
}

添加StockService方法:

public String testRead() {RReadWriteLock rwLock = this.redissonClient.getReadWriteLock("rwLock");rwLock.readLock().lock(10, TimeUnit.SECONDS);System.out.println("测试读锁。。。。");// rwLock.readLock().unlock();return null;
}public String testWrite() {RReadWriteLock rwLock = this.redissonClient.getReadWriteLock("rwLock");rwLock.writeLock().lock(10, TimeUnit.SECONDS);System.out.println("测试写锁。。。。");// rwLock.writeLock().unlock();return null;
}
b5-3.测试
  • 1.打开开两个浏览器窗口测试:
    • 同时访问写:一个写完之后,等待一会儿(约10s),另一个写开始
    • 同时访问读:不用等待
    • 先写后读:读要等待(约10s)写完成
    • 先读后写:写要等待(约10s)读完成

b6. 信号量(Semaphore)
  • 1.基于Redis的Redisson的分布式信号量(Semaphore)Java对象RSemaphore采用了与java.util.concurrent.Semaphore相似的接口和用法。
  • 2.同时还提供了异步(Async)、反射式(Reactive)和RxJava2标准的接口。
RSemaphore semaphore = redisson.getSemaphore("semaphore");
semaphore.trySetPermits(3);
semaphore.acquire();
semaphore.release();
  • 3.在StockController添加方法:
@GetMapping("test/semaphore")
public String testSemaphore(){this.stockService.testSemaphore();return "测试信号量";
}
  • 4.在StockService添加方法:
public void testSemaphore() {RSemaphore semaphore = this.redissonClient.getSemaphore("semaphore");semaphore.trySetPermits(3);try {semaphore.acquire();TimeUnit.SECONDS.sleep(5);System.out.println(System.currentTimeMillis());semaphore.release();} catch (InterruptedException e) {e.printStackTrace();}
}
  • 5.添加测试用例:并发10次,循环一次:
    在这里插入图片描述
  • 6.控制台效果:
控制台11606960790234
1606960800337
1606960800443
1606960805248控制台21606960790328
1606960795332
1606960800245控制台31606960790433
1606960795238
1606960795437
  • 7.由此可知:
    1606960790秒有3次请求进来:每个控制台各1次
    1606960795秒有3次请求进来:控制台2有1次,控制台3有2次
    1606960800秒有3次请求进来:控制台1有2次,控制台2有1次
    1606960805秒有1次请求进来:控制台1有1次
b7. 闭锁(CountDownLatch)
  • 1.基于Redisson的Redisson分布式闭锁(CountDownLatch)Java对象RCountDownLatch采用了与java.util.concurrent.CountDownLatch相似的接口和用法。
RCountDownLatch latch = redisson.getCountDownLatch("anyCountDownLatch");
latch.trySetCount(1);
latch.await();// 在其他线程或其他JVM里
RCountDownLatch latch = redisson.getCountDownLatch("anyCountDownLatch");
latch.countDown();
  • 2.需要两个方法:
    • 一个等待
    • 一个计数countDown给StockController添加测试方法:
@GetMapping("test/latch")
public String testLatch(){this.stockService.testLatch();return "班长锁门。。。";
}
@GetMapping("test/countdown")
public String testCountDown(){this.stockService.testCountDown();return "出来了一位同学";
}
  • 3.给StockService添加测试方法:
public void testLatch() {RCountDownLatch latch = this.redissonClient.getCountDownLatch("latch");latch.trySetCount(6);try {latch.await();} catch (InterruptedException e) {e.printStackTrace();}
}public void testCountDown() {RCountDownLatch latch = this.redissonClient.getCountDownLatch("latch");latch.trySetCount(6);latch.countDown();
}

重启测试,打开两个页面:当第二个请求执行6次之后,第一个请求才会执行。
在这里插入图片描述

相关文章:

redisson中的分布式锁

我的博客大纲 我的后端学习大纲 a.redisson概述&#xff1a; 1.Redisson是一个在Redis的基础上实现的Java驻内存数据网格&#xff08;In-Memory Data Grid&#xff09;2.redisson介绍官方文档地址&#xff1a;3.Redisson它不仅提供了一系列的分布式的Java常用对象&#xff0c;还…...

如何将镜像推送到docker hub

前言 这一篇应该是最近最后一篇关于docker的博客了&#xff0c;咱来个有始有终&#xff0c;将最后一步——上传镜像给他写完&#xff0c;废话不多说&#xff0c;直接进入正题。 登录 首先需要确保登录才能推送到你的仓库中去&#xff0c;在终端输入docker login,输入用户名和…...

GO 匿名函数

GO 匿名函数 文章目录 GO 匿名函数1. **回调函数**2. **goroutine 中的操作**3. **延迟操作&#xff08;defer&#xff09;**4. **内联处理逻辑**5. **闭包**6. **过滤、映射等函数式编程风格**7. **测试中的临时逻辑**8. **短期存在的逻辑操作**总结 匿名函数在 Go 语言中的使…...

JuiceFS 在多云架构中加速大模型推理

在大模型的开发与应用中&#xff0c;数据预处理、模型开发、训练和推理构成四个关键环节。本文将重点探讨推理环节。在之前的博客中&#xff0c;社区用户 BentoML 和贝壳的案例提到了使用 JuiceFS 社区版来提高模型加载的效率。本文将结合我们的实际经验&#xff0c;详细介绍企…...

【DCL】Dual Contrastive Learning for General Face Forgery Detection

文章目录 Dual Contrastive Learning for General Face Forgery Detectionkey points:贡献方法数据视图生成对比学习架构实例间对比学习实例内对比学习总损失函数实验实验细节定量结果跨数据集评估跨操作评估消融实验可视化Dual Contrastive Learning for General Face Forgery…...

https的特点

https的特点 优点&#xff1a;缺点&#xff1a;HTTPS是如何保证安全的&#xff1f; 优点&#xff1a; 使用HTTPS协议可以认证用户和服务器&#xff0c;确保数据发送到正确的客户端和服务器&#xff1b;使用HTTPS协议可以进行加密传输、身份认证&#xff0c;通信更加安全、防止…...

〖open-mmlab: MMDetection〗解析文件:mmdet/models/losses/cross_entropy_loss.py

目录 深入解析MMDetection中的CrossEntropyLoss及其应用1. 概述2. 核心函数2.1 cross_entropy2.1.1 函数定义和参数说明2.1.2 函数体2.1.3 总结 2.2 binary_cross_entropy2.2.1 _expand_onehot_labels函数2.2.2 binary_cross_entropy函数2.2.3 总结 2.3 mask_cross_entropy2.3.…...

【PyTorch单点知识】torch.nn.Embedding模块介绍:理解词向量与实现

文章目录 0. 前言1. 基础介绍1.1 基本参数1.2 可选参数1.3 属性1.4 PyTorch源码注释 2. 实例演示3. embedding_dim的合理设定4. 结论 0. 前言 按照国际惯例&#xff0c;首先声明&#xff1a;本文只是我自己学习的理解&#xff0c;虽然参考了他人的宝贵见解及成果&#xff0c;但…...

Jedis 操作 Redis 数据结构全攻略

Jedis 操作 Redis 数据结构全攻略 一 . 认识 RESP二 . 前置操作2.1 创建项目2.2 关于开放 Redis 端口的问题2.2.1 端口转发?2.2.2 端口配置 2.3 连接到 Redis 服务器 三 . 通用命令3.1 set 和 get3.2 exists 和 del3.3 keys3.4 expire、ttl、type 三 . string 相关命令3.1 mse…...

ctf.show靶场ssrf攻略

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 web351 解析:post传入url参数他就会访问。 解法: hackbar传入url参数写入https://127.0.0.1/flag.php web352 解析:post传入url参数&#xff0c;不能是127.0.0.1和localhost 解法:缩写127.1传入 web353 解析…...

在 PyTorch 中,如何使用 `pack_padded_sequence` 来提高模型训练的效率?

在PyTorch中&#xff0c;pack_padded_sequence 是一个非常有用的函数&#xff0c;它可以用来提高模型训练的效率&#xff0c;特别是在处理变长序列数据时。这个函数的主要作用是将填充后的序列数据打包&#xff0c;以便循环神经网络&#xff08;RNN&#xff09;可以更高效地处理…...

Gossip协议

主要用在Redis Cluster 节点间通信 Gossip协议&#xff0c;也称为流行病协议&#xff08;Epidemic Protocol&#xff09;&#xff0c;是一种在分布式系统中用于信息传播和故障探测的算法。 一、工作原理 随机选择传播对象 每个节点会定期随机选择一些其他节点作为传播对象。这…...

数据结构————双向链表

内存泄漏&#xff1a; 内存泄漏&#xff08;Memory Leak&#xff09;是指程序中已动态分配的内存由于某种原因程序未释放或无法释放&#xff0c;导致系统内存的浪费&#xff0c;严重时会导致程序运行缓慢甚至崩溃。这种情况在长时间运行的程序或大型系统中尤为常见&#xff0c…...

55 - I. 二叉树的深度

comments: true difficulty: 简单 edit_url: https://github.com/doocs/leetcode/edit/main/lcof/%E9%9D%A2%E8%AF%95%E9%A2%9855%20-%20I.%20%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%B7%B1%E5%BA%A6/README.md 面试题 55 - I. 二叉树的深度 题目描述 输入一棵二叉树的根节点…...

Redis——初识Redis

初识Redis Redis认识Redis 分布式系统单机架构为什么要引入分布式理解负载均衡数据库的读写分离引入主从数据库 引入缓存数据库分库分表业务拆分——微服务常见概念了解 Redis背景介绍特性应用场景Redis不能做的事情Redis客户端redis客户端的多种形态 Redis 认识Redis 存储数…...

Xshell or Xftp提示“要继续使用此程序,您必须应用最新的更新或使用新版本”

Xshell提示“要继续使用此程序,您必须应用最新的更新或使用新版本”&#xff0c;笔者版本是xshell 6 方法一&#xff1a;更改系统时间 对于Windows 10用户&#xff0c;首先找到系统日期&#xff0c;右键点击并选择“调整时间/日期”。将日期设定为上一年。完成调整后&#x…...

table用position: sticky固定多层表头,滑动滚动条border边框透明解决方法

问题&#xff1a;我发现&#xff0c;这个上下滑动有内容经过就会出现如图的情况。 解决的方法&#xff1a;用outline&#xff08;轮廓&#xff09;替代border,以达到我们想要的样式。 outline主要是在元素边框的外围设置轮廓&#xff0c;outline不占据空间&#xff0c;绘制于…...

基于飞桨paddle2.6.1+cuda11.7+paddleRS开发版的目标提取-道路数据集训练和预测代码

基于飞桨paddle2.6.1cuda11.7paddleRS开发版的目标提取-道路数据集训练和预测代码 预测结果&#xff1a; 预测影像&#xff1a; &#xff08;一&#xff09;准备道路数据集 下载数据集地址&#xff1a; https://aistudio.baidu.com/datasetdetail/56961 mass_road.zip …...

数学建模笔记—— 整数规划和0-1规划

数学建模笔记—— 整数规划和0-1规划 整数规划和0-1规划1. 模型原理1.1 基本概念1.2 线性整数规划求解1.3 线性0-1规划的求解 2. 典型例题2.1 背包问题2.2 指派问题 3. matlab代码实现3.1 背包问题3.2 指派问题 整数规划和0-1规划 1. 模型原理 1.1 基本概念 在规划问题中&am…...

[001-03-007].第26节:分布式锁迭代3->优化基于setnx命令实现的分布式锁-防锁的误删

我的博客大纲 我的后端学习大纲 1、问题分析&#xff1a; 1.1.问题&#xff1a; 1.锁的超时释放&#xff0c;可能会释放其他服务器的锁 1.2.场景&#xff1a; 1.如果业务逻辑的执行时间是7s。执行流程如下 1.index1业务逻辑没执行完&#xff0c;3秒后锁被自动释放。2.index…...

如何极速获取金融市场数据:5分钟实战指南

如何极速获取金融市场数据&#xff1a;5分钟实战指南 【免费下载链接】qstock qstock由“Python金融量化”公众号开发&#xff0c;试图打造成个人量化投研分析包&#xff0c;目前包括数据获取&#xff08;data&#xff09;、可视化(plot)、选股(stock)和量化回测&#xff08;策…...

Allegro PCB设计必备:3分钟搞定带钻孔数据的DXF文件导出(附常见错误排查)

Allegro PCB设计实战&#xff1a;高效导出带钻孔数据的DXF文件全攻略 在PCB设计领域&#xff0c;Allegro作为行业标杆工具&#xff0c;其文件输出质量直接关系到生产制造的准确性。特别是当设计需要与其他CAD系统协作或提交给PCB制造商时&#xff0c;DXF文件的完整性至关重要。…...

别再手动刷新了!SAP ALV中利用change事件与modify_cell实现智能数据同步

SAP ALV开发进阶&#xff1a;巧用change事件与modify_cell构建智能数据联动体系 在SAP前端开发领域&#xff0c;ALV&#xff08;ABAP List Viewer&#xff09;作为最常用的数据展示控件&#xff0c;其交互体验直接影响用户操作效率。传统开发模式中&#xff0c;当用户修改某个单…...

AI大模型时代:微店商品数据API如何重构反向海淘决策

在AI大模型时代&#xff0c;微店商品数据API凭借覆盖下沉市场、小众货源、私域供给的独特优势&#xff0c;成为重构反向海淘决策的核心支撑&#xff0c;将传统“人工经验判断”升级为“数据采集→AI分析→自动决策→反馈优化”的全链路数据驱动模式&#xff0c;大幅提升选品精准…...

LoRA训练助手入门解析:为什么权重排序对LoRA训练效果影响显著

LoRA训练助手入门解析&#xff1a;为什么权重排序对LoRA训练效果影响显著 1. 认识LoRA训练助手 如果你正在尝试训练自己的AI绘画模型&#xff0c;可能会遇到一个常见问题&#xff1a;为什么同样的图片&#xff0c;用不同的标签训练出来的效果差距那么大&#xff1f;这就是我们…...

人肉区块链:用群体记忆对抗AI篡改

当测试数据面临AI篡改危机在生成式AI全面渗透软件开发生命周期的今天&#xff0c;软件测试从业者正面临前所未有的挑战。AI工具在提升测试用例生成、缺陷预测和日志分析效率的同时&#xff0c;也带来了隐蔽而致命的风险&#xff1a;AI驱动的数据篡改。自动化测试结果被注入虚假…...

ComfyUI-FramePackWrapper功能选择指南:如何根据资源控制与使用便捷性选择最优方案

ComfyUI-FramePackWrapper功能选择指南&#xff1a;如何根据资源控制与使用便捷性选择最优方案 【免费下载链接】ComfyUI-FramePackWrapper 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-FramePackWrapper ComfyUI-FramePackWrapper作为一款高效的AI视频生成插…...

Kindle漫画转换终极方案:如何解决电子阅读器上的格式兼容性问题

Kindle漫画转换终极方案&#xff1a;如何解决电子阅读器上的格式兼容性问题 【免费下载链接】kcc KCC (a.k.a. Kindle Comic Converter) is a comic and manga converter for ebook readers. 项目地址: https://gitcode.com/gh_mirrors/kc/kcc 你是否曾经尝试在Kindle上…...

RouterOS网桥VLAN实战:从零构建安全隔离的二层虚拟网络

1. VLAN基础与RouterOS网桥概述 刚接触网络管理的朋友可能经常听到"VLAN"这个词&#xff0c;但总觉得它神秘莫测。其实VLAN就像给一栋办公楼划分不同部门&#xff1a;财务部、研发部、市场部各自有独立的办公区域&#xff0c;既保证了隐私安全&#xff0c;又避免了相…...

保姆级教程:用CST 2023的RLC求解器搞定空心电感仿真(附网格优化技巧)

从零到精通的CST空心电感仿真实战指南&#xff1a;RLC求解器与网格优化全解析 在电磁兼容设计和高频电路开发中&#xff0c;空心电感作为无磁芯干扰的理想元件&#xff0c;其精确建模一直是工程师的痛点。传统手工计算难以应对复杂的高频效应&#xff0c;而商业仿真软件的门槛…...