悲观锁与乐观锁

一、悲观锁( Pessimistic Lock )

定义与核心思想

悲观锁基于"数据并发必然冲突"的假设,在访问共享资源前强制加锁,确保独占访问。其核心是"先加锁,后操作"的保守策略。

实现方式

1. Java层面

  • synchronized关键字(重量级锁实现)

  • ReentrantLock等显式锁

2. 数据库层面

  • SELECT FOR UPDATE(行级/表级锁)

  • 共享锁(S锁)、排他锁(X锁)

特点与优劣势

优势:

  1. 安全性极高,严格保证数据一致性

  2. 适合临界区执行时间长的场景

劣势:

1.锁开销大(用户态/内核态切换)

2.可能引起线程阻塞、优先级反转

3.死锁风险

二、乐观锁(Optimistic Lock)

定义与核心思想

乐观锁基于"数据冲突概率低"的假设,采用"先操作,后验证"的开放策略,通过版本控制实现无锁化并发。

实现方式

1. 版本号机制

数据表增加version字段,更新时校验版本41518

2. CAS (Compare And Swap )

  • 原子操作包含三个参数:内存值V、预期值A、新值B

  • 仅在V==A时更新为B,否则重试

  • Java实现:AtomicInteger等原子类

特点与优劣势

优势:

  1. 无锁设计提升吞吐量

  2. 避免线程上下文切换

  3. 适合读多写少场景

劣势:

  1. ABA问题(需版本号辅助解决)

  2. 高竞争场景导致频繁重试

  3. 需业务层处理冲突

三、关键差异对比

维度 悲观锁 乐观锁
并发假设 必定冲突 大概率无冲突
锁机制 显式加锁 无锁(版本控制)
冲突处理 预防冲突 检测并解决冲突
适用场景 写操作多、临界区耗时长 读操作多、临界区执行快
实现复杂度 简单(JVM/DB原生支持) 需业务层处理冲突逻辑
典型应用 银行转账、库存扣减 点赞计数、配置更新
性能表现 高安全但吞吐量低 高吞吐但存在重试开销

四、架构选型建议

  1. 优先考虑乐观锁:

    • 当系统读占比超过70%

    • 业务能容忍短暂数据不一致(如缓存更新)

    • 需支持高并发(如电商秒杀库存校验)

  2. 必须使用悲观锁:

    • 强事务一致性要求(如金融交易)

    • 临界区包含复杂计算(避免重复执行)

    • 无法处理重试的场景(如实时竞价系统)

  3. 混合使用策略:

    • 例如JUC中的StampedLock,先尝试乐观读,冲突时升级为悲观锁

五、典型案例

  1. 悲观锁:
java 复制代码
// 使用ReentrantLock转账
   public void transfer(Account from, Account to, int amount) {
       lock.lock();
       try {
           from.withdraw(amount);
           to.deposit(amount);
       } finally {
           lock.unlock();
       }
   }
  1. 乐观锁:
java 复制代码
// 使用AtomicReference实现计数器
   AtomicInteger counter = new AtomicInteger(0);
   public void safeIncrement() {
       int oldValue;
       do {
           oldValue = counter.get();
       } while (!counter.compareAndSet(oldValue, oldValue + 1));
   }

在分布式系统中,可结合Redis的WATCH/MULTI命令实现乐观锁,或通过数据库的版本号字段实现多版本并发控制(MVCC)。实际架构设计中,需结合QPS、数据一致性级别、重试成本等维度综合考量。

相关推荐
刚入门的大一新生2 小时前
Linux-线程互斥
java·开发语言
赵小哥要冲啦3 小时前
社区邻里互助小程序从 0 到 1 复盘:需求拆解与信任机制设计
java·小程序·需求分析
xiaogai_gai3 小时前
采购业务退款单同步实战:从钉钉审批流到金蝶云星空付款单
java·数据库·钉钉
二哈赛车手3 小时前
新人笔记---hermes定时功能设计,具体讲解以及可优化点
java·人工智能·笔记·spring·ai·typescript
ZWZhangYu3 小时前
从 Dify 实践理解大模型上下文缓存
java·后端·spring
小羊没烦恼!3 小时前
关于分布式锁原理的一些学习与思考-redis分布式锁,zookeeper分布式锁
java·服务器·网络·学习·负载均衡
考虑考虑4 小时前
瀚高数据库
数据库·后端·postgresql
Fuyo_11195 小时前
C++ AVL树保姆级详解:从平衡因子到四大旋转机制
java·c++·算法
锋行天下5 小时前
DeepSeek写Langgraph就是个大傻逼,一本正经胡说八道
前端·人工智能·后端
Sarvartha5 小时前
Date、LocalDate、LocalTime、LocalDateTime、DateTimeFormatter类
java