CAS

在 Java 中,CAS(Compare and Swap)是一种无锁的原子操作机制,它可以在不加锁的情况下实现对共享变量的原子更新。

原理

CAS 操作包含三个操作数:内存位置(V)、预期原值(A)和新值(B)。CAS 操作会将内存位置 V 中的值与预期原值 A 进行比较,如果相等,则将内存位置 V 中的值更新为新值 B,否则不进行任何操作。整个操作是原子性的,由硬件指令保证。

实例代码

在 Java 中,可以使用java.util.concurrent.atomic包下的原子类来使用 CAS 操作。例如,AtomicInteger类提供了compareAndSet方法来实现 CAS 操作。

import java.util.concurrent.atomic.AtomicInteger;

public class CASExample {
    public static void main(String[] args) {
        // 创建一个AtomicInteger对象
        AtomicInteger atomicInteger = new AtomicInteger(0);

        // 在线程中使用CAS更新AtomicInteger的值
        Thread thread1 = new Thread(() -> {
            int expectedValue = atomicInteger.get();
            int newValue = expectedValue + 1;
            // 使用CAS更新值,如果更新成功,打印更新后的结果
            if (atomicInteger.compareAndSet(expectedValue, newValue)) {
                System.out.println("Thread 1: Updated value to " + newValue);
            }
        });

        Thread thread2 = new Thread(() -> {
            int expectedValue = atomicInteger.get();
            int newValue = expectedValue + 2;
            // 使用CAS更新值,如果更新成功,打印更新后的结果
            if (atomicInteger.compareAndSet(expectedValue, newValue)) {
                System.out.println("Thread 2: Updated value to " + newValue);
            }
        });

        thread1.start();
        thread2.start();

        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 打印最终的值
        System.out.println("Final value: " + atomicInteger.get());
    }
}

好处

  • 无锁开销:相比于传统的加锁方式,CAS 避免了线程阻塞和唤醒的开销,提高了并发性能。尤其是在高并发场景下,当竞争不激烈时,CAS 能够以较低的成本实现数据的原子更新。
  • 提高并发性:多个线程可以同时尝试使用 CAS 更新共享变量,而不会像使用锁那样导致线程阻塞,从而提高了系统的并发性和吞吐量。

坏处

  • ABA 问题
    如果一个变量 V 初次读取时的值为 A,并且在准备赋值的时候检查到它的值仍然为 A,那不能说明它的值没有被其他线程修改过。因为在这期间它可能被改为其他值,然后又改回了 A。解决 ABA 问题可以使用AtomicStampedReference类,它通过给变量添加版本号来解决 ABA 问题。
  • 自旋开销
    在 CAS 操作失败时,通常会通过自旋(不断重试)来再次尝试更新。如果自旋次数过多,会浪费大量的 CPU 资源。特别是在竞争激烈的情况下,可能导致 CAS 操作长时间无法成功,影响系统性能。
  • 不适用于复杂操作
    CAS 只能对单个变量进行原子操作,对于多个变量的原子更新或者复杂的业务逻辑,CAS 可能无法直接满足需求,需要结合其他技术来实现。
posted @ 2025-03-25 09:57  蒟蒻00  阅读(43)  评论(0)    收藏  举报