【987、乐观锁和悲观锁;CAS】

51 阅读2分钟

** 悲观锁和乐观锁:**

  1. 悲观锁:

    • 定义: 悲观锁是一种假设最坏情况并采取相应措施的并发控制策略。在悲观锁的情况下,认为在事务完成之前,数据很可能会被其他事务所修改,因此在访问数据时先进行加锁,确保其他事务不能同时修改数据。
    • 实例: 传统的关系型数据库中的行级锁就是悲观锁的一种实现方式。当一个事务读取或修改某行数据时,会将该行数据加锁,阻止其他事务同时修改。
  2. 乐观锁:

    • 定义: 乐观锁是一种假设事务冲突的概率很小的并发控制策略。在乐观锁的情况下,事务在进行读取操作时不对数据进行加锁,而是在更新时检查是否有其他事务已经修改了数据。如果没有冲突,就可以成功更新,否则需要处理冲突。
    • 实例: 版本控制是乐观锁的一种实现方式。每个数据记录都有一个版本号,当事务要更新数据时,先检查版本号是否一致,如果一致就更新数据并增加版本号,否则认为有冲突。

CAS(Compare and Swap): CAS是一种乐观锁的实现机制,通常用于多线程并发控制。它包含三个操作数:内存位置V,旧的预期值A,即将要更新的新值B。CAS操作会比较内存位置的值与预期值,如果相符,就将该位置值更新为新值。整个操作是原子的。

实例:

public class Counter {
    private volatile int value;

    public int getValue() {
        return value;
    }

    public void increment() {
        int current;
        int next;
        
        do {
            // 读取当前值
            current = value;
            // 计算新值
            next = current + 1;
            // 使用CAS操作尝试更新值
        } while (!compareAndSet(current, next));
    }

    private synchronized boolean compareAndSet(int expect, int update) {
        // 使用同步方法确保CAS操作的原子性
        if (value == expect) {
            value = update;
            return true;
        }
        return false;
    }
}

在这个例子中,increment方法尝试使用CAS操作更新计数器的值。如果其他线程已经修改了值,CAS操作会失败,循环会重新尝试。这样可以确保计数器的操作是线程安全的。