Java并发编程 - 基础(乐观锁与CAS)

在Java并发编程中,乐观锁(Optimistic Locking)和比较并交换(Compare-and-Swap, CAS)是非常重要的概念,尤其是在实现无锁或低锁的数据结构和算法时。下面将详细介绍这两个概念。

乐观锁(Optimistic Locking)

乐观锁假设数据在大多数情况下不会发生冲突,因此在读取数据时不加锁,只有在更新数据时才检查数据版本是否发生了变化。如果检测到数据版本已更改,则放弃更新并重新开始整个过程。这种方法减少了锁的竞争,提高了系统的吞吐量。

乐观锁的实现方式:
  1. 版本号机制:为数据添加一个版本号字段,在读取数据时记录版本号,在更新数据时先检查版本号是否发生变化。如果发生变化,则更新失败。

  2. CAS操作:使用比较并交换(CAS)操作来实现乐观锁。CAS是一种原子操作,它尝试用期望的新值替换旧值,只有在值没有被其他线程修改的情况下才会成功。

比较并交换(Compare-and-Swap, CAS)

CAS是一种特殊的原子更新操作,它包含三个参数:存储位置(V)、预期原值(A)和新值(B)。如果存储位置的值与预期原值相匹配,则以原子方式将该位置的值设置为新值。否则,操作失败,不会有任何动作发生。

CAS的特点:
  • 原子性:CAS是一个不可分割的操作,要么成功要么失败。
  • 无锁:CAS不需要获取锁就可以完成,减少了锁带来的上下文切换和阻塞等问题。
  • 非阻塞:如果CAS失败,通常会通过循环的方式重试,直到成功为止。
CAS的Java实现

Java提供了 AtomicInteger 类,它是基于CAS操作的。AtomicInteger 使用 Unsafe 类中的 compareAndSwapInt 方法实现CAS。

示例
import java.util.concurrent.atomic.AtomicInteger;

public class CASExample {
    public static void main(String[] args) {
        AtomicInteger counter = new AtomicInteger(0);

        // 尝试将counter从0更新为5
        boolean success = counter.compareAndSet(0, 5);
        if (success) {
            System.out.println("Update successful: " + counter.get());
        } else {
            System.out.println("Update failed.");
        }

        // 尝试将counter从5更新为10
        success = counter.compareAndSet(5, 10);
        if (success) {
            System.out.println("Update successful: " + counter.get());
        } else {
            System.out.println("Update failed.");
        }

        // 尝试将counter从6更新为15(失败)
        success = counter.compareAndSet(6, 15);
        if (success) {
            System.out.println("Update successful: " + counter.get());
        } else {
            System.out.println("Update failed.");
        }
    }
}

在这个例子中,我们创建了一个 AtomicInteger 对象 counter,并尝试使用 compareAndSet 方法更新它的值。如果当前值与预期值相匹配,则更新成功;否则,更新失败。

CAS的局限性

尽管CAS提供了原子性更新和无锁的优点,但它也有几个局限性:

  1. ABA问题:如果一个值被更新为另一个值后又变回原来的值,那么CAS操作会误认为没有发生改变。这个问题可以通过使用版本号或者带有时间戳的引用等方法来解决。

  2. 循环时间开销:如果CAS操作频繁失败,会导致大量的循环重试,从而增加CPU的负担。

  3. 只能保证一个共享变量的原子性:当有多个共享变量需要原子性操作时,单个CAS操作无法保证整体的原子性。

综上所述,乐观锁和CAS操作在Java并发编程中扮演着重要角色,尤其适用于那些希望减少锁竞争的应用场景。然而,开发者需要充分了解这些技术的局限性,并采取适当措施来克服这些问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值