乐观锁和悲观锁详解 @ Lin | 2024-09-30T15:21:26+08:00 | 2 分钟阅读 | 更新于 2024-09-30T15:21:26+08:00

乐观锁和悲观锁详解

1. 核心概念对比

悲观锁(Pessimistic Lock)

定义
假设共享资源每次访问都会发生冲突,每次操作前加锁,其他线程需阻塞等待锁释放。
类比现实
类似“未雨绸缪”的人,总假设最坏情况,提前预防问题。 • 实现方式
Java 中通过 synchronizedReentrantLock 等独占锁实现。

代码示例

// synchronized 示例
public void performSynchronisedTask() {
    synchronized (this) {
        // 需要同步的操作
    }
}

// ReentrantLock 示例
private Lock lock = new ReentrantLock();
lock.lock();
try {
    // 需要同步的操作
} finally {
    lock.unlock();
}

优缺点

优点:避免数据竞争,保证强一致性。
缺点
• 高并发下锁竞争激烈,导致线程阻塞和上下文切换,性能开销大。
• 可能引发死锁(如锁顺序不当)。


乐观锁(Optimistic Lock)

定义
假设共享资源访问不会冲突,操作时不加锁,提交修改时验证数据是否被修改。
类比现实
类似“乐观”的人,假设最好情况,快速解决问题。
实现方式
通过 版本号机制CAS 算法 实现。Java 中如 AtomicIntegerLongAdder

代码示例

// LongAdder 示例(高并发性能更优,空间换时间)
LongAdder sum = new LongAdder();
sum.increment();

优缺点

优点
• 无锁竞争,无死锁问题,读多写少场景性能更优。
缺点
• 写冲突频繁时,大量失败重试,影响性能(可通过 LongAdder 等优化)。
• 仅适用于单共享变量场景。


2. 乐观锁实现技术

版本号机制

原理
数据表中添加 version 字段,每次修改 version+1。提交更新时,校验当前 version 是否与读取时一致。 • 示例
账户余额修改场景中,通过版本号避免并发更新覆盖问题。

CAS 算法(Compare And Swap)

原理
原子操作,依赖 CPU 指令,比较变量当前值(V)与预期值(E),相等时更新为新值(N)。
三要素
V(变量值)、E(预期值)、N(新值)。
特点
• 失败线程可重试或放弃,无阻塞。
• 需处理 ABA 问题(需额外机制如版本号)。


3. 适用场景总结

锁类型 适用场景 典型实现
悲观锁 写多读少,竞争激烈 synchronized, ReentrantLock
乐观锁 读多写少,冲突较少 AtomicInteger, LongAdder

4. 扩展阅读

《Java 并发编程核心 78 讲》
涵盖悲观锁、乐观锁、可重入锁、自旋锁等详细实现与实战分析。

© 2019 - 2025 Lin 的博客

Powered by Hugo with theme Dream.

avatar
关于我

Lin 的 ❤️ 博客

记录一些 🌈 生活上,技术上的事

职业是JAVA全栈工程师