Java中的CAS(Compare-And-Swap)操作示例详解

 更新时间:2025年06月06日 11:02:01   作者:二进制11  
CAS是一种原子操作,用于在多线程环境中实现无锁(lock-free)的线程安全编程,下面通过本文给大家介绍Java中的CAS(Compare-And-Swap)操作示例详解,感兴趣的朋友一起看看吧

Java面试题 - 什么是Java 的 CAS(Compare-And-Swap)操作?

什么是CAS操作?

CAS(Compare-And-Swap,比较并交换)是一种原子操作,用于在多线程环境中实现无锁(lock-free)的线程安全编程。它是现代并发编程中的基础操作之一,Java中的许多并发工具类(如AtomicInteger、AtomicReference等)都是基于CAS实现的。

CAS操作包含三个操作数:

  • 内存位置(V)
  • 预期原值(A)
  • 新值(B)

当且仅当内存位置V的值等于预期原值A时,处理器才会将该位置的值更新为新值B,否则不执行任何操作。无论哪种情况,都会返回该位置原来的值。

CAS操作的基本流程

Java中的CAS实现

在Java中,CAS操作主要通过sun.misc.Unsafe类提供的一系列方法实现,这些方法最终会调用本地(native)方法,由JVM借助CPU的CAS指令完成。

Java并发包(java.util.concurrent.atomic)中的原子类(如AtomicInteger)提供了对CAS操作的封装:

public class AtomicInteger extends Number implements java.io.Serializable {
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private volatile int value;
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }
    // 其他方法...
}

CAS操作示例

下面是一个使用AtomicInteger的简单示例:

import java.util.concurrent.atomic.AtomicInteger;
public class CASExample {
    private static AtomicInteger counter = new AtomicInteger(0);
    public static void main(String[] args) {
        // 初始值为0
        System.out.println("初始值: " + counter.get());
        // 尝试将0更新为1(会成功)
        boolean success1 = counter.compareAndSet(0, 1);
        System.out.println("CAS(0,1)结果: " + success1 + ", 当前值: " + counter.get());
        // 尝试将0更新为2(会失败,因为当前值已经是1)
        boolean success2 = counter.compareAndSet(0, 2);
        System.out.println("CAS(0,2)结果: " + success2 + ", 当前值: " + counter.get());
    }
}

输出结果:

初始值: 0
CAS(0,1)结果: true, 当前值: 1
CAS(0,2)结果: false, 当前值: 1

CAS的典型应用场景

  • 原子类:如AtomicInteger、AtomicLong、AtomicReference等
  • 并发容器:如ConcurrentHashMap的部分实现
  • 锁机制:如AQS(AbstractQueuedSynchronizer)的实现基础
  • 计数器:无锁的线程安全计数器

CAS的优缺点

优点

  • 高性能:避免了线程阻塞和上下文切换的开销
  • 无锁:减少了死锁的可能性
  • 可扩展性:在高并发环境下表现良好

缺点

  • ABA问题:如果一个值从A变成B,然后又变回A,CAS会认为它没有变化过
    • 解决方案:使用版本号或时间戳(如AtomicStampedReference)

  • 循环时间长开销大:如果CAS失败,通常会循环重试,长时间不成功会消耗CPU资源
  • 只能保证一个共享变量的原子操作:对于多个共享变量,需要使用AtomicReference来封装

CAS与锁的比较

特性CAS
线程阻塞不会阻塞(乐观锁)会阻塞(悲观锁)
实现复杂度较高相对简单
适用场景低冲突、简单操作高冲突、复杂操作
性能无上下文切换,开销小有上下文切换,开销大
公平性不保证公平性可保证公平性

总结

CAS是Java并发编程中的重要概念,它提供了一种高效的无锁线程安全机制。理解CAS的工作原理对于编写高性能并发程序至关重要。虽然CAS有ABA问题等局限性,但通过适当的解决方案(如版本号)可以规避这些问题。在适当的场景下使用CAS,可以显著提高程序的并发性能。

到此这篇关于Java中的CAS(Compare-And-Swap)操作示例详解的文章就介绍到这了,更多相关Java CAS操作内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java中Arthas的作用和使用方式

    java中Arthas的作用和使用方式

    Arthas 是由阿里巴巴开源的 Java 诊断工具,主要用于在生产环境中诊断和解决 Java 应用问题,它提供实时监控、类信息查看、动态追踪、条件表达式断点等功能,支持非侵入式设计和高扩展性,通过 Arthas,开发者可以在不停止应用的情况下,快速定位和解决问题
    2025-01-01
  • Java日期工具类DateUtils实例详解

    Java日期工具类DateUtils实例详解

    这篇文章主要为大家详细介绍了Java日期工具类DateUtils实例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • java多线程通过CompletableFuture组装异步计算单元

    java多线程通过CompletableFuture组装异步计算单元

    这篇文章主要为大家介绍了java多线程通过CompletableFuture组装异步计算单元,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • Java Maven依赖传递,可选依赖,排除依赖详解

    Java Maven依赖传递,可选依赖,排除依赖详解

    这篇文章主要介绍了Java Maven依赖传递,可选依赖,排除依赖详解,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • Java之String[] args含义及作用

    Java之String[] args含义及作用

    这篇文章主要介绍了Java之String[] args含义及作用,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • springboot 整合EhCache实现单服务缓存的操作方法

    springboot 整合EhCache实现单服务缓存的操作方法

    这篇文章主要介绍了springboot 整合EhCache实现单服务缓存的操作方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • Java 中 String、StringBuffer、StringBuilder 的区别

    Java 中 String、StringBuffer、StringBuilder 的区别

    本文主要介绍了Java 中 String、StringBuffer、StringBuilder 的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2026-05-05
  • Spring中配置Transaction与不配置的区别及说明

    Spring中配置Transaction与不配置的区别及说明

    这篇文章主要介绍了Spring中配置Transaction与不配置的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • Java Listener监听器使用规范详细介绍

    Java Listener监听器使用规范详细介绍

    监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动。监听器其实就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变
    2023-01-01
  • java Object wait方法详细介绍

    java Object wait方法详细介绍

    这篇文章主要介绍了java Object wait方法详细介绍的相关资料,需要的朋友可以参考下
    2017-02-02

最新评论