在Java里AtomicInteger如何保证原子性_Java原子类CAS机制解析

AtomicInteger通过CAS指令与volatile变

量实现无锁原子性,底层调用Unsafe执行CPU级原子操作,配合循环重试和volatile的可见性/有序性保障线程安全。

AtomicInteger 通过底层的 CAS(Compare-And-Swap) 指令 + volatile 变量语义 实现原子性,不依赖锁,而是靠 CPU 硬件指令保障单次读-改-写操作的不可中断性。

底层基于 Unsafe 的 CAS 操作

AtomicInteger 内部持有 volatile int value,并通过 sun.misc.Unsafe 类调用本地方法执行 CAS:

  • CAS 是一条 CPU 原子指令(如 x86 的 cmpxchg),在硬件层面保证“比较并交换”一步完成,不会被线程调度打断
  • Unsafe.getObjectVolatile / Unsafe.compareAndSwapInt 等方法将 Java 调用映射到该指令
  • 失败时返回 false,通常配合循环重试(如 incrementAndGet() 中的 for 循环),实现乐观锁逻辑

volatile 保证可见性与有序性

仅靠 CAS 不足以保证多线程下的正确性,value 字段被声明为 volatile:

  • 写操作后立即刷回主内存,避免线程间值不同步
  • 禁止编译器和处理器对 volatile 读写做重排序,确保 CAS 前后的内存操作顺序可控
  • 注意:volatile 本身不保证复合操作(如 i++)原子性,但 AtomicInteger 把它封装进了 CAS 循环里

为什么不用 synchronized?

对比传统锁,CAS 在低竞争场景下性能更高:

  • 无上下文切换、无阻塞、无锁升级开销
  • 适合计数器、序列号生成、状态标志等简单状态更新场景
  • 高竞争时可能引发大量 CAS 失败和重试(ABA 问题虽存在但对 AtomicInteger 影响有限,因它只关心数值是否变化,不关心中间过程)

典型方法背后的原子逻辑

incrementAndGet() 为例:

  • 读取当前 value(volatile 读)
  • 计算 next = value + 1
  • 执行 CAS:若当前值仍等于刚读出的 value,则设为 next;否则重试
  • 整个过程无锁、无阻塞、线程安全

基本上就这些。CAS + volatile 是 Java 原子类的基石,理解它,就抓住了无锁编程的核心。