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

在C#中的乐观锁和悲观锁

在C#中,乐观锁(Optimistic Locking)和悲观锁(Pessimistic Locking)是两种不同的并发控制策略,用于处理多线程环境下的数据一致性问题。它们的核心区别在于对数据冲突的预期和处理方式。

1. 悲观锁(Pessimistic Locking)

悲观锁假设在多线程环境下,数据冲突是常态,因此在访问共享资源时,会提前锁定资源,防止其他线程的干扰。

特点
  • 提前锁定:在操作数据之前,先获取锁,确保独占访问。
  • 适用场景:适用于写操作频繁、冲突概率较高的场景。
  • 缺点:可能导致锁竞争,降低并发性能。
实现方式

在C#中,悲观锁可以通过lock关键字、Monitor类、Mutex类等实现。

示例
public class Counter
{private int count = 0;private readonly object lockObject = new object();public void Increment(){lock (lockObject) // 悲观锁:提前锁定{count++;}}public int GetCount(){lock (lockObject) // 悲观锁:提前锁定{return count;}}
}

2. 乐观锁(Optimistic Locking)

乐观锁假设在多线程环境下,数据冲突是少数情况,因此不会提前锁定资源,而是在提交操作时检查数据是否被其他线程修改过。如果数据被修改,则放弃操作或重试。

特点
  • 不提前锁定:在操作数据时不加锁,仅在提交时检查冲突。
  • 适用场景:适用于读操作频繁、写操作较少的场景。
  • 优点:减少锁竞争,提高并发性能。
  • 缺点:需要处理冲突,可能会导致操作失败或重试。
实现方式

乐观锁通常通过版本号(Version Number)或时间戳(Timestamp)来检测数据是否被修改。

示例
public class Counter
{private int count = 0;private int version = 0; // 版本号public void Increment(){int currentVersion;int newVersion;do{currentVersion = version; // 获取当前版本号newVersion = currentVersion + 1; // 计算新版本号} while (Interlocked.CompareExchange(ref version, newVersion, currentVersion) != currentVersion);// 如果版本号更新成功,说明没有冲突count++;}public int GetCount(){return count;}
}

3. 对比

特点悲观锁乐观锁
锁定时机提前锁定,操作开始时加锁不提前锁定,仅在提交时检查冲突
适用场景写操作频繁,冲突概率高读操作频繁,写操作较少
并发性能低(锁竞争)高(减少锁竞争)
实现方式lockMonitorMutex版本号(Version Number)、时间戳(Timestamp)
优点简单,容易实现提高性能,减少锁竞争
缺点锁竞争,性能瓶颈需要处理冲突,可能重试

4. 使用场景

  • 悲观锁
    • 适用场景:数据库事务中,当更新操作频繁且冲突概率较高时,使用悲观锁可以避免频繁的冲突处理。
    • 示例:银行转账系统,多个线程同时操作同一个账户余额。
  • 乐观锁
    • 适用场景:读操作频繁,写操作较少的场景,如在线购物系统中,商品信息的读取和更新。
    • 示例:电商平台的商品库存更新,读取操作远多于写入操作。

5. 在数据库中的应用

  • 悲观锁
    • 在数据库中,可以通过SELECT FOR UPDATE语句实现悲观锁,锁定记录,防止其他事务修改。
    • 示例:
      SELECT * FROM products WHERE id = 1 FOR UPDATE;
      
  • 乐观锁
    • 在数据库中,可以通过版本号或时间戳字段实现乐观锁。在更新时,检查版本号是否发生变化。
    • 示例:
      UPDATE products SET stock = stock - 1, version = version + 1 WHERE id = 1 AND version = @currentVersion;
      

总结

  • 悲观锁:适合写操作频繁、冲突概率高的场景,通过提前锁定资源来避免冲突。
  • 乐观锁:适合读操作频繁、写操作较少的场景,通过版本号或时间戳检测冲突,减少锁竞争,提高并发性能。

在实际开发中,可以根据具体需求选择合适的锁机制。


文章转载自:

http://WNkgBctv.prfrb.cn
http://6WgUeZ5N.prfrb.cn
http://azCQOf1j.prfrb.cn
http://5izxlcZ6.prfrb.cn
http://ArensWIa.prfrb.cn
http://z30FeXP7.prfrb.cn
http://gBxEnGWi.prfrb.cn
http://6KlkGBZn.prfrb.cn
http://1XUcUX8t.prfrb.cn
http://mx4iyf2e.prfrb.cn
http://qNwqOAzj.prfrb.cn
http://nWBlXJPW.prfrb.cn
http://IgZ1xMnl.prfrb.cn
http://ltdfrivh.prfrb.cn
http://BQq04qEb.prfrb.cn
http://rjjBYVFj.prfrb.cn
http://hC5LXSW4.prfrb.cn
http://fvqkFw4p.prfrb.cn
http://8UeuXtDZ.prfrb.cn
http://HO2Ph1Nv.prfrb.cn
http://kRTlOARv.prfrb.cn
http://dE5jyL6H.prfrb.cn
http://gWwSeCvH.prfrb.cn
http://JnwHYiKY.prfrb.cn
http://Ee4Dvy2b.prfrb.cn
http://YB8FAFe8.prfrb.cn
http://EmL81SyU.prfrb.cn
http://iJHWK639.prfrb.cn
http://DzoBfpdG.prfrb.cn
http://mTtZIXmH.prfrb.cn
http://www.dtcms.com/a/248121.html

相关文章:

  • 智能出入库管理系统:自动化管控平台
  • 高级定时器TIM1、TIM8
  • AD工程面板拖动以及固定位置
  • AWS WebRTC:通过shell实现多进程启动master
  • AWS知识点和技术面试模拟题
  • 29-Oracle 23ai Flashback Log Placement(闪回日志灵活配置)
  • AWS S3:云存储的“超级基石”
  • AWS Well-Architected Framework详解
  • 30-Oracle 23ai-回顾从前的Flashback设置
  • 基于CT图像的硬参数共享多任务分析:肝脏肿瘤分割与良恶性分类
  • Terraform跨云迁移教程:从AWS到阿里云基础设施同步 (2025)
  • HarmonyOS 5中UniApp的调试步骤
  • 后端开发:计算机网络、数据库常识
  • 大模型现在用的最多 其次是预训练模型,大模型用于rag agent 预训练模型用于微调任务
  • 鸿蒙Next仓颉语言开发实战教程:订单详情
  • 重新定义声音处理:XMOS XVF3800、DOA与Beamforming技术的深度解析
  • SNN学习(4):真实的生物神经学中神经元和人脑结构学习
  • 数据库分库分表情况下数据统计的相关问题详解(面试问答)
  • Grok 官方镜像站全新上线
  • 在GIS 工作流中实现数据处理(4)
  • 蚂蚁集团法人变更:韩歆毅接任,公司治理的正常安排
  • 轻量级密码算法CHAM的python实现
  • xa_get_mark 简介
  • Redis分布式锁解决多实例同时执行定时任务的问题以及扫描延时任务时对桶的获取问题
  • HBase 安装与简单操作指南
  • 【jmeter】报告怎么看
  • ELK日志文件分析系统——1
  • 布局和约束相关的生命周期(layoutIfNeeded,updateConstraintsIfNeeded)
  • 洛谷:B4163 [BCSP-X 2024 12 月初中组] 序列选择
  • [网络实验] Cisco Packet Tracer | 通信子网的拓扑设计