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

redis--Redisson的八种锁机制

Redisson 的8种锁机制

Redisson 应用最多的场景就是其分布式锁RLock。

而RLock只是Redisson 线程同步方案之一。Redisson 提供了8种线程同步方案。可以针对不同场景选择不同方案。

为了避免锁到期但业务没执行完毕而引发并发问题,Redisson 内部提供了一个监控锁的看门狗 watch dog,其会在锁到期前不断延长锁的到期时间,直到锁被主动释放。即自动完成“锁续命”。

可重入锁

Redisson 的RLock是可重入锁。当一个线程获取到锁后,这个线程可以再次获取本对象上的锁,而其他线程不可以。

  • JDK中的ReentrantLock是可重入锁,其是通过AQS(抽象队列同步器)实现的锁机制
  • synchronized 也是可重入锁,其是通过监视器模式(本质是os的互斥锁)实现的锁机制

公平锁

Redisson 的可重入锁RLock默认是非公平锁,但也支持可重入公平锁FailLock.

多个线程同时申请锁时,这些线程会进入到一个FIFO队列,只有队首元素会获取到锁,其他元素等待。当锁被释放后,再将锁分配给当前的队首元素。

 // 获取到公平锁,公平锁是按照请求锁的顺序来获取锁的,先请求锁的先获取到锁,后请求锁的后获取到锁。RLock rlock = redisson.getFairLock(Redis_lock);

联锁

Redisson 联锁MultiLock .

当一个线程要处理多个共享资源时,可以使用联锁。

即一次性申请多个锁,同时锁定多个资源。

联锁可预防死锁,对共享资源的申请实现了原子性;要么都申请到,要么都申请不到;

其是OS底层原理中AND型信号量机制的典型应用。

    RLock rlock1 = redisson1.getLock(Redis_lock+"_1");RLock rlock2 = redisson2.getLock(Redis_lock+"_2");RLock rlock3 = redisson3.getLock(Redis_lock+"_3");// 2. 构建联锁(MultiLock)RedissonMultiLock multiLock = new RedissonMultiLock(rlock1, rlock2, rlock3);

红锁

Redisson 红锁 RedLock。红锁由多个锁构成,当大部分这里的大部分锁申请成功,红锁才申请成功。

红锁一般用于解决Redis 主从集群锁丢失问题。

红锁与联锁的区别:

  • 红锁实现对一个共享资源的同步访问控制
  • 联锁实现对多个共享资源的同步访问控制
     	RLock rlock1 = redisson1.getLock(Redis_lock+"_1");RLock rlock2 = redisson2.getLock(Redis_lock+"_2");RLock rlock3 = redisson3.getLock(Redis_lock+"_3");RedissonRedLock rlock = new RedissonRedLock(rlock1,rlock2,rlock3);

读写锁

Redisson 读写锁 RReadWriteLock. 通过RReadWriteLock实例可获取到读锁RedissonReadLock和RedissonWriteLock.

读锁和写锁分别实现了RLock的可重入锁。

一个共享资源,在没有写锁的情况下,允许加多个读锁。只要加了写锁,就不能加任何读锁与写锁。

读锁是共享锁,写锁为排他锁。

  		RReadWriteLock readWriteLock = redisson.getReadWriteLock(Redis_lock);RLock rLock = readWriteLock.readLock();RLock rLock1 = readWriteLock.writeLock();

信号量

Redisson 可以获取到信号量RSemaphore。RSemaphore的常用场景有两种:

  1. 无论谁加的锁,其他线程都可以解锁
  2. 当一个线程要申请多个资源时

RSemaphore 时信号量机制的典型应用。

      // 假设Redis中存储key="redis_semaphore"的值为8,表示有8个信号量可用。RSemaphore redisSemaphore = redisson.getSemaphore("redis_semaphore");try {// 申请一个信号 ,信号量-1redisSemaphore.acquire();// 一次申请3个信号,信号量-3redisSemaphore.tryAcquire(3);// 申请一个信号,等待时间为10秒,redisSemaphore.tryAcquire(10, TimeUnit.SECONDS);// 一次申请3个信号,等待时间为10秒,redisSemaphore.tryAcquire(3,10, TimeUnit.SECONDS);} catch (InterruptedException e) {throw new RuntimeException(e);}finally {// 释放一个信号,信号量+1redisSemaphore.release();// 一次释放3个信号,信号量+3redisSemaphore.release(3);}

可过期信号量

Redisson 可以获取到可过期信号量 PermitExpirableSemaphore .

它是在RSemaphore 基础上,为每个信号增加了过期时间,且每个信号通过独立的ID来辨识。释放时只能通过提交该ID才能释放。

一个线程每次只能申请一个信号量,每次也只能释放一个信号量。(与RSemaphore 不同的地方)

该信号量为互斥信号量时,等同于可重入锁。或者说,可重入锁就相当于信号量为1的可过期信号量。

可过期信号量与可重入锁的区别:

  • 可重入锁:用户每次只能申请1个信号量,且只有一个用户可以申请成功
  • 可过期信号量:用户没每次只能申请1个信号量,但可以有多个用户申请成功
 RPermitExpirableSemaphore redisSemaphore1 = redisson.getPermitExpirableSemaphore("redis_semaphore");String permitId="";try {// 申请一个信号,信号量-1,返回一个permitId,释放锁的时候需要用到这个permitIdpermitId = redisSemaphore1.acquire();} catch (InterruptedException e) {throw new RuntimeException(e);}finally {// 释放一个信号,信号量+1,释放锁的时候需要用到这个permitIdredisSemaphore1.release(permitId);}

分布式闭锁

Redisson 可以获取到分布式闭锁 RCountDownLatch. 与JUC中的闭锁CountDownLatch原理相同,用法类似。常用于一个或多个线程的执行必须在其他任务执行完毕的场景。

例如:大规模分布式并行计算中,最终的合并计算必须基于很多的并向计算的计算结果。

闭锁中定义了一个计数器和一个阻塞队列。

阻塞队列中存放着待执行的线程。每当一个并行任务执行完毕,计数器就 -1 ,当计数器=0时,就会唤醒阻塞队列的所有线程。

通常使用Barrier 队列解决该问题,而Barrier 队列通常使用Zookeeper 实现。

  		// 获取闭锁对象(合并线程和条件线程都需要该代码)RCountDownLatch countDownLatch = redisson.getCountDownLatch("count_down_latch");// 合并线程代码// 当闭锁的计数器为0或者闭锁不存在时,初始化闭锁的计数器为3if(countDownLatch.getCount() == 0 || !countDownLatch.isExists()){// 初始化闭锁的计数器为3,countDownLatch.trySetCount(3);}try {// 合并线程等待闭锁,等待条件线程执行完毕后,合并线程才会继续执行countDownLatch.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}// ==============================================================================// 条件线程代码// 条件线程执行完毕后,调用countDown方法,闭锁的计数器-1,当计数器为0时,合并线程才会继续执行countDownLatch.countDown();
http://www.jsqmd.com/news/810684/

相关文章:

  • Sunshine游戏串流实战秘籍:打造你的个人云端游戏厅 [特殊字符]
  • 如何利用libui-node生态构建跨平台桌面应用:Proton-Native和Vuido深度解析
  • 一、纳指ETF—简要
  • DashPress主题定制教程:从颜色方案到品牌标识
  • 告别傻等!用CANoe Test Node的TestWait函数,让你的自动化测试脚本更智能
  • 终极指南:Windows上无需模拟器安装安卓应用的完整教程
  • 自动化脚本编排:如何在青龙面板中构建多服务定时任务系统
  • 毫米波雷达ADAS实战:TI AWR1843芯片上的信号处理链优化心得(附FFT与CFAR配置要点)
  • 滴滴充电获行业大奖,以用户价值驱动充电体验升级,开放生态布局未来
  • 从零配置到IEEE投稿级输出:Perplexity引用格式自动化工作流(含Python脚本+JSON Schema模板)
  • 【故障诊断】基于淘金优化算法GRO优化双向时间卷积神经网络BiTCN实现轴承数据故障诊断附Matlab代码
  • 机场FOD异物检测实战:YOLOv8多模态网络(可见光+红外+毫米波雷达)融合全流程
  • ssm+vue智慧养老中心管理系统(10020)
  • 终极解决方案:如何轻松突破Cursor试用限制的完整指南
  • 【LangChain】结构化输出
  • 手把手教你用USB转TTL调试GPS北斗模块(附串口助手配置与常见问题排查)
  • Windows 下 Codex 安装全记录:从零到一的保姆级图文教程
  • Friends
  • ARMCC(Keil)编译器输出文件全解析:从源码到可执行映像的构建之旅
  • DocX安全特性完全指南:文档保护、密码加密和数字签名终极教程
  • 从High-NA EUV到波长微缩:半导体光刻技术的未来路径与核心挑战
  • 为内部知识库问答机器人接入 Taotoken 多模型聚合 API
  • 基于矢量光速螺旋时空归一化体系的引力 - 电磁统一最小场模型:荷质比 K 的动力学起源与低能匹配条件
  • 博德之门3模组管理终极指南:5分钟快速上手BG3ModManager
  • 技术深度解析:5大核心要点掌握Sunshine开源游戏串流服务器实战部署
  • CSDN会员推广伙伴招募:分销返佣 + 资源互换,诚邀合作
  • 5个颠覆性技巧:用GanttProject开源甘特图工具让你的项目管理效率提升200%
  • 基于PCA主成分分析的BP神经网络回归预测研究(Matlab代码实现)
  • AMOLED像素艺术工具开发:从画布渲染到嵌入式代码导出全解析
  • Illustrator脚本自动化终极指南:如何节省设计师90%重复工作时间