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操作内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBean管理与Spring Boot自动配置原理解析

    SpringBean管理与Spring Boot自动配置原理解析

    在Spring中,Bean的作用域(Scope)决定了Bean的实例化方式以及其生命周期,下面给大家介绍SpringBean管理与Spring Boot自动配置原理解析,感兴趣的朋友一起看看吧
    2025-05-05
  • Spring使用aop切面编程时要给那些类加注解的实例

    Spring使用aop切面编程时要给那些类加注解的实例

    在使用切面编程时,通常需要为以下类或组件添加注解来标识它们,以便 Spring 或其他切面框架能够正确识别和处理它们,这篇文章主要介绍了Spring使用aop切面编程时要给那些类加注解,需要的朋友可以参考下
    2023-11-11
  • java编程实现屏幕截图(截屏)代码总结

    java编程实现屏幕截图(截屏)代码总结

    这篇文章主要介绍了java编程实现屏幕截图(截屏)代码,结合3个实例总结分析了Java截屏时页面抓取及图片保存的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-11-11
  • spring boot结合Redis实现工具类的方法示例

    spring boot结合Redis实现工具类的方法示例

    这篇文章主要介绍了spring boot结合Redis实现工具类的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11
  • Java字母加数字组合比较大小

    Java字母加数字组合比较大小

    这篇文章主要通过实现Comarable接口来比较(如"a20"和"a9"这种)字符串的大小,希望能给大家做一个参考。
    2016-06-06
  • 详解Java的内置异常以及创建自定义异常子类的方法

    详解Java的内置异常以及创建自定义异常子类的方法

    这篇文章主要介绍了详解Java的内置异常以及创建自定义异常子类的方法,是Java入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • iOS多线程介绍

    iOS多线程介绍

    这篇文章主要介绍了iOS多线程的相关知识,涉及到对进程,线程等方面的知识讲解,本文非常具有参考价值,感兴趣的朋友一起学习吧
    2016-05-05
  • MyBatis中insert操作返回主键的实现方法

    MyBatis中insert操作返回主键的实现方法

    在使用MyBatis做持久层时,insert语句默认是不返回记录的主键值,而是返回插入的记录条数。这篇文章主要介绍了MyBatis中insert操作返回主键的方法,需要的朋友可以参考下
    2016-09-09
  • Java-Io-RandomAccessFile任意位置读写数据的操作小结

    Java-Io-RandomAccessFile任意位置读写数据的操作小结

    RandomAccessFile类支持随机访问方式,可以跳转到文件的任意位置读写数据,这个类在文件随机读取时有很大的优势,可利用多线程完成对一个大文件的读写,本文给大家介绍Java-Io-RandomAccessFile(任意位置读写数据)的相关知识,需要的朋友可以参考下
    2022-05-05
  • Java利用JSONPath操作JSON数据的技术指南

    Java利用JSONPath操作JSON数据的技术指南

    JSONPath 是一种强大的工具,用于查询和操作 JSON 数据,类似于 SQL 的语法,它为处理复杂的 JSON 数据结构提供了简单且高效的解决方案,本文将介绍 JSONPath 的基本语法,并通过详细的 Java 示例展示其实际应用,需要的朋友可以参考下
    2025-04-04

最新评论