Redisson分布式锁:原理、使用

1. Redisson简介

Redisson是一个基于Redis的Java客户端库,提供了丰富的分布式对象和服务(如分布式锁、信号量、Map等)。其核心优势在于​​简化分布式锁的实现​​,并解决了原生Redis分布式锁的常见问题(如死锁、误删锁等)。


2. Redisson分布式锁核心特性

2.1 锁类型

  • ​可重入锁(RLock)​​:同一线程可重复获取同一把锁。
  • ​公平锁(FairLock)​​:按请求顺序分配锁,避免饥饿现象。
  • ​联锁(MultiLock)​​:一次性锁定多个资源。
  • ​红锁(RedLock)​​:基于多Redis实例的高可用锁。

可重入锁(RLock)

可重入锁是Redisson最基础的锁类型,允许同一线程多次获取同一把锁而不会造成死锁。其核心原理是:

  • ​数据结构​​:使用Redis的Hash结构存储锁信息,key为锁名称,field为线程标识(UUID+threadId),value为重入次数
  • ​重入机制​​:当线程首次获取锁时,计数器设为1;同一线程再次获取时计数器递增,释放时递减,直到计数器归零才真正释放锁
  • ​Lua脚本保证原子性​​:加锁和解锁操作都通过Lua脚本实现,确保操作的原子性
// 获取可重入锁示例
RLock lock = redisson.getLock("myLock");
lock.lock();  // 第一次获取锁
try {lock.lock();  // 同一线程再次获取锁(重入)// 执行业务逻辑
} finally {lock.unlock();  // 释放锁(计数器减1)lock.unlock();  // 完全释放锁(计数器归零)
}

公平锁(FairLock)

公平锁按照请求顺序分配锁资源,解决线程饥饿问题:

  • ​排队机制​​:使用Redis的List结构实现等待队列(redisson_lock_queue:{lockName}),ZSet结构记录超时时间(redisson_lock_timeout:{lockName})
  • ​公平获取​​:新线程获取锁时,必须检查自己是否是队列头部,只有队首线程才能获取锁
  • ​超时清理​​:定期清理队列中超时的线程请求,避免无效等待
// 公平锁使用示例
RLock fairLock = redisson.getFairLock("fairLock");
fairLock.lock();
try {// 公平执行业务逻辑
} finally {fairLock.unlock();
}

联锁(MultiLock)

联锁用于同时锁定多个资源:

  • ​原子性操作​​:将多个RLock组合成一个锁,所有锁必须全部获取成功才算成功
  • ​严格互斥​​:默认要求所有锁都必须成功获取(failedLocksLimit=0)
  • ​适用场景​​:如订单系统中需要同时锁定多个商品库存的场景
// 联锁使用示例
RLock lock1 = redisson.getLock("lock1");
RLock lock2 = redisson.getLock("lock2");
RLock lock3 = redisson.getLock("lock3");RedissonMultiLock multiLock = new RedissonMultiLock(lock1, lock2, lock3);
multiLock.lock();
try {// 同时操作多个受保护资源
} finally {multiLock.unlock();
}

红锁(RedLock)

红锁是基于多Redis实例的高可用锁:

  • ​多数派原则​​:在N个独立Redis节点上获取锁,至少成功(N/2 +1)个才算获取成功
  • ​容错机制​​:即使部分节点故障,只要多数节点正常就能保证锁可用
  • ​解决主从问题​​:避免主从切换导致的锁失效问题
// 红锁使用示例
RLock lock1 = redisson1.getLock("lock1");
RLock lock2 = redisson2.getLock("lock2");
RLock lock3 = redisson3.getLock("lock3");RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);
redLock.lock();
try {// 执行高可用要求的业务逻辑
} finally {redLock.unlock();
}


2.2 关键机制

  • ​看门狗自动续期​​:默认30秒检查一次,若业务未完成则延长锁过期时间。
  • ​锁超时释放​​:避免死锁,支持手动设置leaseTime
  • ​非阻塞尝试​​:通过tryLock(0, ...)实现立即返回。

3. 代码示例

3.1 基础锁使用

// 1. 获取RedissonClient实例(需提前配置Redis连接)
RedissonClient redisson = Redisson.create(config);// 2. 获取锁对象(锁键为"myLock")
RLock lock = redisson.getLock("myLock");try {// 3. 尝试获取锁,waitTime=0表示不重试,leaseTime=10秒表示锁自动释放时间boolean isLocked = lock.tryLock(0, 10, TimeUnit.SECONDS);if (isLocked) {// 4. 执行业务逻辑System.out.println("锁获取成功,执行业务...");} else {System.out.println("锁获取失败,直接返回");}
} catch (InterruptedException e) {Thread.currentThread().interrupt();System.out.println("线程被中断");
} finally {// 5. 释放锁(需判断当前线程是否持有锁)if (lock.isLocked() && lock.isHeldByCurrentThread()) {lock.unlock();}
}

3.2 注解式锁(Spring集成)

@Service
public class InventoryService {private int stock = 100;// 使用@Lock注解声明分布式锁(锁键为"decreaseStockLock")@Lock(name = "decreaseStockLock")public void decreaseStock() {if (stock > 0) {stock--;System.out.println("库存扣减成功,剩余: " + stock);}}
}

4. 最佳实践

  1. ​避免锁过期​​:若业务耗时不确定,建议不设置leaseTime(启用看门狗)。
  2. ​防误删锁​​:在unlock()前校验锁持有者(isHeldByCurrentThread())。
  3. ​非阻塞场景​​:使用tryLock(0, ...)快速失败。

5.对比总结

特性可重入锁公平锁联锁红锁
核心特点同一线程可重复获取按请求顺序分配同时锁定多个资源多节点高可用
数据结构Hash结构Hash+List+ZSet多个RLock组合多个独立节点锁
适用场景一般并发控制避免线程饥饿多资源原子操作高可用要求场景
性能影响中等(需维护队列)高(需获取所有锁)高(多节点通信)

参加:腾讯元宝

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/75970.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java大厂面试题 -- JVM 优化进阶之路:从原理到实战的深度剖析(2)

最近佳作推荐: Java大厂面试题 – 深度揭秘 JVM 优化:六道面试题与行业巨头实战解析(1)(New) 开源架构与人工智能的融合:开启技术新纪元(New) 开源架构的自动化测试策略优…

MySQL学习笔记(四)——DML和DQL

目录 1. DML 1.1 添加数据 1.1.1 给指定字段添加数据 1.1.2 给全部字段添加数据 1.1.3 批量添加数据 1.2 修改数据 1.3 删除数据 2. DQL 2.1 基本语法 2.2 基础查询 2.2.1 查询多个字段 2.2.2 字段设置别名 2.2.3 去除重复记录 2.3 条件查询 2.4 聚合函数 2.5 …

DeepSeek-MLA

MLA 结构 需要缓存 KV 向量共用的压缩隐特征K 向量多头共享的带位置编码的向量 为什么带有位置信息的 Q 向量来自于隐特征向量,而带有位置的 K 向量来自于 H 向量且共享呢? 最好的方法肯定是从H向量直接计算并且不共享,但是会大大增加显存使…

检索增强技术RAG和向量数据库技术的优势和劣势,应用范围和价值

RAG 和向量数据库在技术栈中处于不同层级,前者侧重生成任务的准确性与动态性,后者专注检索效率与扩展性。在实际应用中,二者常协同工作,但也可独立服务于不同场景。企业需根据需求选择:若需生成内容,RAG 是…

Python爬虫教程013:使用CrawlSpider爬取读书网数据并保存到mysql数据库

文章目录 3.8 CrawlSpider介绍3.9 CrawlSpider爬取读书网案例3.9.1 创建项目3.9.2 定义要爬取的数据结构3.9.3 获取数据3.9.4 保存数据到本地3.9.5 保存数据到mysql数据库3.9.6 完整项目下载3.8 CrawlSpider介绍 CrawlSpider 是 Scrapy 框架中 最常用的高级爬虫类之一,用于构…

Three.js 系列专题 5:加载外部模型

内容概述 Three.js 支持加载多种 3D 文件格式(如 GLTF、OBJ、FBX),这让开发者可以直接使用专业建模软件(如 Blender、Maya)创建的复杂模型。本专题将重点介绍 GLTF 格式的加载,并调整模型的位置和材质。 学习目标 理解常见 3D 文件格式及其特点。掌握使用 GLTFLoader 加…

P1006 [NOIP 2008 提高组] 传纸条 题解

题目传送门 前言 每次准备摸鱼时都在这道题的界面。 今天有空做做,顺便写一波题解,毕竟估值蹭蹭往下跳。 双倍经验:P1004 [NOIP 2000 提高组] 方格取数,P1006 [NOIP 2008 提高组] 传纸条。 题意简述 现有一个 m m m 行 n …

LLM架构解析:长短期记忆网络(LSTM)(第三部分)—— 从基础原理到实践应用的深度探索

本专栏深入探究从循环神经网络(RNN)到Transformer等自然语言处理(NLP)模型的架构,以及基于这些模型构建的应用程序。 本系列文章内容: NLP自然语言处理基础词嵌入(Word Embeddings&#xff09…

ffmpeg提取字幕

使用ffmpeg -i test.mkv 获取视频文件的字幕流信息如下 Stream #0:4(chi): Subtitle: subrip (srt) (default) Metadata: title : chs Stream #0:5(chi): Subtitle: subrip (srt) Metadata: title : cht Stream #0:6(jpn)…

Python设计模式:构建模式

1. 什么是构建模式 构建模式(Builder Pattern)是一种创建型设计模式,它允许使用多个简单的对象一步步构建一个复杂的对象。构建模式通过将构建过程与表示分离,使得同样的构建过程可以创建不同的表示。换句话说,构建模…

使用 VIM 编辑器对文件进行编辑

一、VIM 的两种状态 VIM(vimsual)是 Linux/UNIX 系列 OS 中通用的全屏编辑器。vim 分为两种状态,即命令状态和编辑状态,在命令状态下,所键入的字符系统均作命令来处理;而编辑状态则是用来编辑文本资料&…

GaussDB回调机制深度实践:从事件驱动到系统集成

GaussDB回调机制深度实践:从事件驱动到系统集成 一、回调机制核心概念 回调类型矩阵 二、核心实现技术栈 触发器回调开发 sql -- 创建审计触发器回调 CREATE OR REPLACE FUNCTION audit_trigger() RETURNS TRIGGER AS $$ BEGININSERT INTO audit_log (operati…

AI小白:AI算法中常用的数学函数

文章目录 一、激活函数1. Sigmoid2. ReLU(Rectified Linear Unit)3. Tanh(双曲正切)4. Softmax示例代码:激活函数的实现 二、损失函数1. 均方误差(MSE)2. 交叉熵损失(Cross-Entropy&…

idea 打不开terminal

IDEA更新到2024.3后Terminal终端打不开的问题_idea terminal打不开-CSDN博客

Python代码list列表的使用和常用方法及增删改查

Python代码list列表的使用和常用方法及增删改查 提示:帮帮志会陆续更新非常多的IT技术知识,希望分享的内容对您有用。本章分享的是Python基础语法。前后每一小节的内容是存在的有:学习and理解的关联性,希望对您有用~ python语法-p…

Open CASCADE学习|读取点集拟合样条曲线(续)

问题 上一篇文章已经实现了样条曲线拟合,但是仍存在问题,Tolerance过大拟合成直线了,Tolerance过大头尾波浪形。 正确改进方案 1️⃣ 核心参数优化 通过调整以下参数控制曲线平滑度: Standard_Integer DegMin 3; // 最低阶…

Python基础知识点(列表与字典)

列表list[] # list [12,34,56,78] # print(list) """ 1.list可以保存同一类型的数据 或 不同类型的数据 2.list是有序的,所以可以通过[下标]访问元素 3.list保存重复的值 4.list是可变的,可以添加 删除元素 """ …

在 Elasticsearch 中使用 Amazon Nova 模型

作者:来自 Elastic Andre Luiz 了解如何在 Elasticsearch 中使用 Amazon Nova 系列模型。 在本文中,我们将讨论 Amazon 的 AI 模型家族——Amazon Nova,并学习如何将其与 Elasticsearch 结合使用。 关于 Amazon Nova Amazon Nova 是 Amazon …

MySQL8.0.40编译安装(Mysql8.0.40 Compilation and Installation)

MySQL8.0.40编译安装 近期MySQL发布了8.0.40版本,与之前的版本相比,部分依赖包发生了变化,因此重新编译一版,也便于大家参考。 1. 下载源码 选择对应的版本、选择源码、操作系统 如果没有登录或者没有MySQL官网账号&#xff0…

python中pyside6多个py文件生成exe

网上见到的教程大多数都是pyinstaller安装单个py文件,针对多个py文件的打包,鲜有人提及;有也是部分全而多的解释,让人目不暇接,本次记录自己设置一个声波捕捉界面的打包过程。 1.pycharm中调用pyinstaller打包 参考链接:https://blog.csdn.net/weixin_45793544/articl…