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

高并发下的锁选择:乐观锁 vs 悲观锁全面对比

目录

1. 乐观锁 (Optimistic Lock)

核心思想

实现机制

代码示例

优缺点

适用场景

2. 悲观锁 (Pessimistic Lock)

核心思想

实现机制

代码示例

优缺点

适用场景

3. 公平锁 (Fair Lock) vs 非公平锁 (Non-fair Lock)

公平锁

非公平锁

对比表格

4. 综合对比


1. 乐观锁 (Optimistic Lock)

核心思想

先操作,后检查冲突。假设并发冲突的概率很低,允许多个线程同时访问资源,只在提交时检查是否有冲突。

实现机制

  1. 版本号/时间戳:为数据增加一个版本字段

  2. CAS操作:Compare-And-Swap,比较并交换

  3. 流程:读取数据 → 修改数据 → 验证版本号 → 如果验证通过则提交,否则重试或失败

代码示例

UPDATE products 
SET stock = stock - 1, version = version + 1 
WHERE id = 100 AND version = 5;
// Java CAS示例
AtomicInteger atomicInt = new AtomicInteger(0);
atomicInt.compareAndSet(0, 1); // 如果当前值是0,则设置为1

优缺点

优点

  1. 并发性能高,减少线程阻塞

  2. 适合读多写少的场景

缺点

  1. 冲突时需要重试,可能产生自旋开销

  2. 不保证操作一定成功

适用场景

  1. 数据库并发更新

  2. 购物车库存扣减

  3. 社交媒体点赞功能

2. 悲观锁 (Pessimistic Lock)

核心思想

先加锁,后操作。假设并发冲突的概率很高,每次操作前先获取锁,确保独占访问。

实现机制

  1. synchronized:Java内置锁

  2. ReentrantLock:可重入锁

  3. 数据库行锁:SELECT ... FOR UPDATE

代码示例

public synchronized void criticalSection() {// 线程安全代码
}// Java ReentrantLock
ReentrantLock lock = new ReentrantLock();
lock.lock();
try {// 线程安全代码
} finally {lock.unlock();
}
 
START TRANSACTION;
SELECT * FROM accounts WHERE id = 1 FOR UPDATE;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;

优缺点

优点

  1. 保证数据强一致性

  2. 编程模型简单

缺点

  1. 并发性能较低,线程阻塞

  2. 可能产生死锁

适用场景

  1. 银行转账交易

  2. 订单支付处理

  3. 需要强一致性的金融系统

3. 公平锁 (Fair Lock) vs 非公平锁 (Non-fair Lock)

公平锁

按照请求顺序分配锁,先到先得。

ReentrantLock fairLock = new ReentrantLock(true); // true表示公平锁

特点

  1. 线程按申请顺序获取锁

  2. 不会出现线程饥饿现象

  3. 性能相对较低(需要维护队列)

非公平锁

允许插队,后申请的线程可能先获取到锁。

ReentrantLock nonFairLock = new ReentrantLock(); // 默认非公平锁
ReentrantLock nonFairLock = new ReentrantLock(false);

特点

  1. 吞吐量更高,减少线程切换

  2. 可能造成线程饥饿

  3. 性能更好

对比表格

特性公平锁非公平锁
获取顺序先进先出允许插队
性能较低较高
线程饥饿不会可能
实现复杂度较高较低

4. 综合对比

维度乐观锁悲观锁
并发性
开销冲突时开销大始终有开销
数据一致性最终一致性强一致性
适用场景读多写少写多读少
实现方式版本号、CASsynchronized、ReentrantLock

文章转载自:

http://IRpShIqG.zcyxq.cn
http://rFQJpW8F.zcyxq.cn
http://jCd3Q37v.zcyxq.cn
http://Tn6mLh5B.zcyxq.cn
http://HrMSUHwo.zcyxq.cn
http://IfIvscyL.zcyxq.cn
http://qutd4a3j.zcyxq.cn
http://xfXYpRgH.zcyxq.cn
http://h2KdCsiZ.zcyxq.cn
http://GdimZlH1.zcyxq.cn
http://Piftnipl.zcyxq.cn
http://mpbxXTL6.zcyxq.cn
http://OBdwgCs6.zcyxq.cn
http://dpiK4rbZ.zcyxq.cn
http://7DI49Kts.zcyxq.cn
http://SBWbKvmS.zcyxq.cn
http://0eLyrQrv.zcyxq.cn
http://ULcLymUe.zcyxq.cn
http://LMDJN9JN.zcyxq.cn
http://ZcC4VHR7.zcyxq.cn
http://cSNboCp2.zcyxq.cn
http://n1C2FqkX.zcyxq.cn
http://i0u2lF8m.zcyxq.cn
http://BqPRLNxh.zcyxq.cn
http://a1VtJDxj.zcyxq.cn
http://yfg5mcWO.zcyxq.cn
http://MzHne0T7.zcyxq.cn
http://Uiypan4N.zcyxq.cn
http://krVH29JJ.zcyxq.cn
http://2UXO5eCU.zcyxq.cn
http://www.dtcms.com/a/374193.html

相关文章:

  • 本地部署大模型和知识库实现问答AI
  • python编程:一文掌握pypiserver的详细使用
  • 【人工智能99问】开源项目RAGflow_by_infiniflow介绍(37/99)
  • Qt C++ 复杂界面处理:巧用覆盖层突破复杂界面处理难题​之一
  • 一种高效绘制余晖波形的方法Qt/C++
  • 本地部署的Qwen3,测试不同数量并发请求的吞吐量
  • 【从零开始java学习|第十三篇】字符串究极知识总结
  • Linux内核进程管理子系统有什么第四十六回 —— 进程主结构详解(42)
  • Kafka 与 RocketMQ 核心概念与架构对比
  • 【检索通知】2025年IEEE第二届深度学习与计算机视觉国际会议检索
  • 2025年AC-DC电源模块选购指南与应用方案解析
  • LeetCode 面试经典 150 题:删除有序数组中的重复项 II(最多保留 2 次 + 通用 k 次解法详解)
  • 在OpenHarmony上适配图形显示【2】——调试display hdi的技巧
  • 在 JavaScript 中轻松实现 AES 加密与解密:从原理到实战
  • Mockoon:开源免费的本地Mock服务工具,提升前后端联调效率
  • C/C++圣诞树②
  • segYolo添加界面
  • 初学Transformer核心——注意力机制
  • 第9篇:Freqtrade量化交易之config.json 基础入门与初始化
  • 推荐系统学习笔记(十六)LHUC(PPNet)
  • 前端开发实战 主流前端开发工具对比与最佳实践
  • 淘宝 API 技术架构与实战指南:从实时数据流到 AIGC 融合的电商开发新范式
  • 基于AD9689BBPZ-2600 的高速数字采集 板卡
  • Transformer 模型:Attention is All You Need 的真正含义
  • BUU MISC(看心情写)
  • 第三方网站数据库测评:【源码级SQL注入与数据泄露风险全面测评】
  • 【Linux基础】parted命令详解:从入门到精通的磁盘分区管理完全指南
  • 实践《数字图像处理》之Canny边缘检测、霍夫变换与主动二值化处理在短线段清除应用中的实践
  • sim2real_动作迁移常用的方法和思路(比如bvh->robot)
  • 第六届机器学习与计算机应用国际学术会议