浅析锁的应用与场景

锁的应用与场景:从单机到分布式

摘要:在多线程和分布式系统中,“锁”是避免资源竞争、保障数据一致性的核心机制。但你真的了解锁吗?什么时候该用锁?用哪种锁?本文通过通俗的比喻和代码示例,带你彻底搞懂锁的应用场景!


一、为什么需要锁?

想象一下:多人同时编辑同一份文档,如果不加控制,最终文档内容会乱成一锅粥。程序中的共享资源(如数据库字段、文件、内存变量)同样面临这个问题——锁的作用就是让多个线程/进程“排队”访问资源

常见问题场景:

  1. 订单重复处理:用户疯狂点击提交订单,导致重复扣款。
  2. 超卖问题:秒杀活动中库存被减到负数。
  3. 数据覆盖:两个线程同时修改用户余额,后者覆盖前者结果。

二、单机环境下的锁

1. 乐观锁 vs 悲观锁

  • 悲观锁:假设一定会发生冲突,先加锁再操作。
    • 应用场景:冲突频繁、临界区代码执行时间长。

    • 实现方式

      • 数据库:SELECT ... FOR UPDATE
      • Java:synchronizedReentrantLock
维度synchronizedReentrantLock
锁管理JVM 自动管理,无需手动释放需手动获取和释放,易忘记导致死锁
灵活性功能简单,仅支持非公平锁支持公平锁、超时、中断、多条件变量
性能JVM 优化后性能接近(低竞争场景更优)高并发场景更灵活(如 tryLock 减少竞争)
调试支持锁信息不易获取(如等待队列长度)提供 isLocked(), getQueueLength() 等方法
适用场景简单同步需求(如单方法内的线程安全)复杂同步逻辑(如多条件协调、精细控制)
  • 乐观锁:假设冲突很少,先操作再检查是否冲突。
    • 应用场景:读多写少、冲突概率低。
    • 实现方式
      • 数据库:版本号(Version字段)+ CAS更新
      • Java:AtomicIntegerStampedLock
代码示例:数据库乐观锁
-- 1. 查询时获取版本号
SELECT stock, version FROM product WHERE id = 1;-- 2. 更新时校验版本号
UPDATE product SET stock = stock - 1, version = version + 1 
WHERE id = 1 AND version = 1; -- 如果version被修改过,更新失败

2. 读写锁(ReadWriteLock)

  • 核心思想:读操作不互斥,写操作互斥。
  • 应用场景:读多写少,如缓存系统。
  • Java实现ReentrantReadWriteLock
ReadWriteLock rwLock = new ReentrantReadWriteLock();// 读操作
rwLock.readLock().lock();
try {// 读取数据(允许多个线程同时读)
} finally {rwLock.readLock().unlock();
}// 写操作
rwLock.writeLock().lock();
try {// 修改数据(独占锁)
} finally {rwLock.writeLock().unlock();
}

三、分布式锁

当服务部署在多台机器上时(即使在同一台物理机上的多个容器/Pod),单机锁失效,必须使用分布式锁协调跨进程的资源访问。

1. 常见实现方案

方案核心原理优点缺点
Redis锁SETNX + 过期时间 + Lua脚本删除性能高,实现简单存在锁过期提前释放风险
ZooKeeper创建临时顺序节点,监听前序节点删除可靠性高,自动释放锁性能较低,需要维护ZK集群
数据库锁基于唯一索引或行级锁无需额外组件性能差,高并发易成瓶颈
  • 高并发且允许偶发锁失效:Redis + Redisson。
  • 强一致性需求:ZooKeeper 或 Etcd。
  • 简单场景:数据库(不推荐生产环境高频使用)

2. Redis分布式锁示例(Redisson实现)

// 1. 获取锁对象
RLock lock = redissonClient.getLock("orderLock");// 2. 尝试加锁(等待10秒,锁自动释放时间30秒)
boolean isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS);
if (isLocked) {try {// 处理业务逻辑processOrder();} finally {lock.unlock();}
}

四、如何选择合适的锁?

1. 决策流程图

在这里插入图片描述

2. 黄金原则

  • 能用单机锁就别用分布式锁(复杂度陡增)
  • 锁粒度要小:锁住的范围越小,性能越高
  • 优先考虑无锁设计:如使用线程安全的类(ConcurrentHashMap)、本地线程存储(ThreadLocal

五、避坑指南

  1. 死锁:避免嵌套锁,设置超时时间。
  2. 锁饥饿:公平锁可缓解,但性能会下降。
  3. 锁泄露:确保finally块中释放锁。
  4. 脑裂问题(分布式锁):选择强一致性协调器(如ZooKeeper)。

六、总结

  • 单机多线程:本地锁 + 数据库唯一索引即可满足需求,无需分布式锁。优先选synchronizedReentrantLock
  • 多机/多实例:必须引入分布式锁,同时结合数据库约束保证最终安全。
  • 高并发读:读写锁(ReadWriteLock)是救星。
  • 分布式系统:Redis锁(性能)或ZooKeeper锁(可靠性)二选一。
  • 终极目标:在安全性和性能之间找到平衡!

技术没有银弹,理解场景才能选出最合适的锁!

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

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

相关文章

30天通过软考高项-第三天

30天通过软考高项-第三天 任务:项目范围管理 思维导图阅读 知识点集锦阅读 知识点记忆 章节习题练习 知识点练习 手写回忆ITTO 听一遍喜马拉雅关于范围的内容 范围管理-背 1. 过程定义 规划变瘦订份缺孔 规划范围管理:为了记录如何定…

文字过长使用省略号展示,text-overflow 的使用和不生效场景的解决办法,flex 布局中文字省略展示的坑

在前端开发过程中【单行文本内容过长使用省略号展示】这是一个特别常见的功能,大家都知道要使用 text-overflow 这个 css 属性。 关于这个属性,我们可以先看一下官方文档怎么说。 text-overflow CSS 属性用于确定如何提示用户存在隐藏的溢出内容。其形式…

(二)读写分离架构、冷热分离架构

文章目录 读写分离架构什么是读写分离结构架构模型优缺点优点缺点 技术案例写情况读情况 冷热分离架构什么是冷热分离架构?架构模型优缺点优点 缺点技术案例读数据写数据 读写分离架构 什么是读写分离结构 读写分离架构针对于数据库。数据库原本负责读写两个功能。 读写分离架…

windows中kafka4.0集群搭建

参考文献 Apache Kafka windows启动kafka4.0(不再需要zookeeper)_kafka压缩包-CSDN博客 Kafka 4.0 KRaft集群部署_kafka4.0集群部署-CSDN博客 正文 注意jdk需要17版本以上的 修改D:\software\kafka_2.13-4.0.0\node1\config\server.properties配置文…

无线通信网

注意区分CA(无线)和CD(有线) 无线局域网扩频技术 FHSS/DSSS 无线频谱和信道:2.4G/5GHz,2.4GHz共13个信道,3个不重叠信道 CSMA/CA,隐藏节点 MANET 无线安全:WEP、WPA、WPA2、AES/TP…

嵌入式开发:基础知识介绍

一、嵌入式系统 1、介绍 以提高对象体系智能性、控制力和人机交互能力为目的,通过相互作用和内在指标评价的,嵌入到对象体系中的专用计算机系统。 2、分类 按其形态的差异,一般可将嵌入式系统分为:芯片级(MCU、SoC&am…

uv包管理器如何安装依赖?

uv包管理器如何安装依赖? 输入 uv pip install 包名 uv pip install python-docx

大模型驱动智能服务变革:从全流程赋能到行业纵深落地

大模型技术的快速发展,正深刻改变着人工智能的研发与应用模式。作为"软硬协同、开箱即用"的智能化基础设施,大模型一体机通过整合计算硬件、部署平台和预置模型,重构了传统AI部署方式,成为推动AI普惠化和行业落地的重要…

【MQ篇】RabbitMQ之简单模式!

目录 引言一、 初识 RabbitMQ 与工作模式二、 简单模式 (Simple Queue) 详解:最直接的“点对点快递” 📮三、 Java (Spring Boot) 代码实战:让小兔子跑起来! 🐰🏃‍♂️四、 深入理解:简单模式的…

Lua 第7部分 输入输出

由于 Lua 语言强调可移植性和嵌入性 , 所以 Lua 语言本身并没有提供太多与外部交互的机制 。 在真实的 Lua 程序中,从图形、数据库到网络的访问等大多数 I/O 操作,要么由宿主程序实现,要么通过不包括在发行版中的外部库实现。 单就…

【开源】STM32HAL库移植Arduino OneWire库驱动DS18B20和MAX31850

项目开源链接 github主页https://github.com/snqx-lqh本项目github地址https://github.com/snqx-lqh/STM32F103C8T6HalDemo作者 VXQinghua-Li7 📖 欢迎交流 如果开源的代码对你有帮助,希望可以帮我点个赞👍和收藏 项目说明 最近在做一个项目…

【合新通信】浸没式液冷光模块与冷媒兼容性测试技术报告

一、测试背景与核心挑战 行业需求驱动 随着800G/1.6T光模块功耗突破30W/端口,传统风冷已无法满足散热需求,浸没式液冷成为超算/AI数据中心的主流方案。冷媒兼容性是系统可靠性的关键指标,涉及材料腐蚀、光学性能、长期稳定性等维度。 核心…

Pandas中的日期时间date处理

Pandas提供了强大的日期和时间处理功能,这对于时间序列分析至关重要。本教程将介绍Pandas中处理日期时间的主要方法。包括: 日期时间数据的创建和转换日期时间属性的提取时间差计算和日期运算重采样和频率转换时区处理基于日期时间的索引操作 Pandas中…

Vue3文件上传组件实战:打造高效的Element Plus上传解决方案,可以对文件进行删除,查看,下载功能。

在现代Web开发中,文件上传功能是许多应用的核心需求之一。无论是企业管理系统、内容管理系统还是医疗信息系统,上传附件的功能都至关重要。本文将分享一个基于 Vue3 和 Element Plus 实现的文件上传组件,结合父子组件的协作,展示如何构建一个功能强大、用户体验友好的文件上…

AI 工程师崛起:科技浪潮下的新兴力量

在当今科技迅猛发展的时代,人工智能(AI)无疑是最热门的领域之一。随着基础模型的涌现和开源 / API 的普及,一种新兴的职业 ——AI 工程师,正逐渐崭露头角。他们在 AI 技术的应用和开发中扮演着关键角色,其崛…

人工智能与机器学习:Python从零实现逻辑回归模型

🧠 向所有学习者致敬! “学习不是装满一桶水,而是点燃一把火。” —— 叶芝 我的博客主页: https://lizheng.blog.csdn.net 🌐 欢迎点击加入AI人工智能社区! 🚀 让我们一起努力,共创…

济南国网数字化培训班学习笔记-第二组-5节-输电线路设计

输电线路设计 工程设计阶段划分 35kv及以上输变电工程勘测设计全过程 可行性研究(包括规划、工程选站)(包括电力系统一次二次,站址选择及工程设想,线路工程选择及工程设想,节能降耗分析,环境…

【Linux网络】TCP服务中IOService应用与实现

📢博客主页:https://blog.csdn.net/2301_779549673 📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! &…

Linux 怎么找Java程序的监听的端口

Linux 怎么找Java程序的监听的端口 1、假设你知道启动该Java应用的进程ID (PID),可以通过以下命令查找其监听的端口: 首先找到该Java应用的PID: ps -ef | grep xxxx-1.0-RELEASE.jar或者,如果你知道启动命令的一部分&#xff0…

解读《数据资产质量评估实施规则》:企业数据资产认证落地的关键指南

随着“数据要素市场”建设加速,数据资产逐步成为企业核心资产之一。2024年4月,由中国质量认证中心(CQC)发布的《数据资产质量评估实施规则》(编号:CQC96-831160-2024)正式实施,为企业…