一、CASCompare And Swap1. 基本概念CAS 是一种乐观锁实现包含三个操作数内存值 V当前主内存中的值预期值 A线程本地记录的旧值新值 B要更新的值核心逻辑只有当 V A 时才将 V 更新为 B否则重试。2. 底层实现// Unsafe 类中的 CAS 操作底层调用 CPU 指令publicfinalnativebooleancompareAndSwapInt(Objecto,longoffset,intexpected,intx);硬件层面现代 CPU 提供 cmpxchg 指令x86或 LDREX/STREXARM保证操作的原子性。3. 典型应用类说明AtomicInteger/AtomicLong原子整型AtomicReference原子引用AtomicStampedReference解决 ABA 问题带版本号ConcurrentHashMap分段锁 CAS 优化ABA 问题问题描述值从 A → B → ACAS 检测不出变化。解决方案AtomicStampedReference 增加版本号/时间戳。AtomicStampedReferenceIntegerrefnewAtomicStampedReference(100,0);int[]stampHoldernewint[1];Integervalueref.get(stampHolder);// 获取值和版本号ref.compareAndSet(100,200,stampHolder[0],stampHolder[0]1);5. CAS 的优缺点优点缺点无锁性能高无线程切换开销只能保证单个变量的原子性非阻塞不会死锁循环重试消耗 CPU自旋存在 ABA 问题二、AQSAbstractQueuedSynchronizer1. 基本概念AQS 是 JUC并发包的基石是一个用于构建锁和同步器的抽象框架。核心设计state 变量int 类型表示同步状态如重入锁的重入次数、信号量的许可数FIFO 队列CLH 变体的双向链表管理等待线程模板方法模式子类只需实现特定方法2. 核心结构3. 两种模式模式说明代表类独占模式同一时间只有一个线程能获取ReentrantLock共享模式多个线程可同时获取Semaphore、CountDownLatch4. 核心方法子类需实现// 独占模式protectedbooleantryAcquire(intarg);// 获取锁protectedbooleantryRelease(intarg);// 释放锁// 共享模式protectedinttryAcquireShared(intarg);// 获取共享锁protectedbooleantryReleaseShared(intarg);// 释放共享锁// 通用protectedbooleanisHeldExclusively();// 是否被独占5. 队列节点Node状态状态值含义CANCELLED1节点被取消超时或中断SIGNAL-1后继节点需要被唤醒CONDITION-2在 Condition 队列中PROPAGATE-3共享模式传播6. 获取锁的流程以 ReentrantLock 为例7. 核心源码分析// AQS 获取锁的入口publicfinalvoidacquire(intarg){if(!tryAcquire(arg)// 1. 快速尝试获取acquireQueued(addWaiter(Node.EXCLUSIVE),arg))// 2. 入队 排队获取selfInterrupt();// 3. 恢复中断状态}// 入队操作CAS 保证线程安全privateNodeaddWaiter(Nodemode){NodenodenewNode(Thread.currentThread(),mode);Nodepredtail;if(pred!null){node.prevpred;if(compareAndSetTail(pred,node)){// CAS 入队pred.nextnode;returnnode;}}enq(node);// 初始化或重试returnnode;}8. AQS 应用同步器模式用途ReentrantLock独占可重入互斥锁ReentrantReadWriteLock独占共享读写分离锁Semaphore共享限流/资源池CountDownLatch共享等待多线程完成CyclicBarrier共享线程互相等待Phaser共享分阶段任务三、CAS vs AQS维度CASAQS层级底层原子操作上层同步框架机制乐观锁无锁悲观锁 队列适用场景简单变量更新复杂同步控制线程冲突重试自旋阻塞 park/unpark CPU 消耗高冲突时较高阻塞后较低关系AQS 内部用 CAS 维护 state 和队列四、实际应用1. 基于 CAS 的原子计数器AtomicIntegercounternewAtomicInteger(0);// 底层CAS 循环直到成功counter.incrementAndGet();基于 AQS 的自定义锁classSimpleLockextendsAbstractQueuedSynchronizer{OverrideprotectedbooleantryAcquire(intarg){returncompareAndSetState(0,1);// CAS 修改 state}OverrideprotectedbooleantryRelease(intarg){setState(0);returntrue;}publicvoidlock(){acquire(1);}publicvoidunlock(){release(1);}}五、总结CAS 是 Java 实现无锁并发的底层利器适用于低竞争、简单场景AQS 是构建复杂同步器的框架通过 state CLH 队列 CAS 实现了高效的线程阻塞与唤醒两者相辅相成AQS 内部大量依赖 CAS 操作如 compareAndSetState、compareAndSetTail
Java随笔-CASAQS
发布时间:2026/7/3 1:43:07
一、CASCompare And Swap1. 基本概念CAS 是一种乐观锁实现包含三个操作数内存值 V当前主内存中的值预期值 A线程本地记录的旧值新值 B要更新的值核心逻辑只有当 V A 时才将 V 更新为 B否则重试。2. 底层实现// Unsafe 类中的 CAS 操作底层调用 CPU 指令publicfinalnativebooleancompareAndSwapInt(Objecto,longoffset,intexpected,intx);硬件层面现代 CPU 提供 cmpxchg 指令x86或 LDREX/STREXARM保证操作的原子性。3. 典型应用类说明AtomicInteger/AtomicLong原子整型AtomicReference原子引用AtomicStampedReference解决 ABA 问题带版本号ConcurrentHashMap分段锁 CAS 优化ABA 问题问题描述值从 A → B → ACAS 检测不出变化。解决方案AtomicStampedReference 增加版本号/时间戳。AtomicStampedReferenceIntegerrefnewAtomicStampedReference(100,0);int[]stampHoldernewint[1];Integervalueref.get(stampHolder);// 获取值和版本号ref.compareAndSet(100,200,stampHolder[0],stampHolder[0]1);5. CAS 的优缺点优点缺点无锁性能高无线程切换开销只能保证单个变量的原子性非阻塞不会死锁循环重试消耗 CPU自旋存在 ABA 问题二、AQSAbstractQueuedSynchronizer1. 基本概念AQS 是 JUC并发包的基石是一个用于构建锁和同步器的抽象框架。核心设计state 变量int 类型表示同步状态如重入锁的重入次数、信号量的许可数FIFO 队列CLH 变体的双向链表管理等待线程模板方法模式子类只需实现特定方法2. 核心结构3. 两种模式模式说明代表类独占模式同一时间只有一个线程能获取ReentrantLock共享模式多个线程可同时获取Semaphore、CountDownLatch4. 核心方法子类需实现// 独占模式protectedbooleantryAcquire(intarg);// 获取锁protectedbooleantryRelease(intarg);// 释放锁// 共享模式protectedinttryAcquireShared(intarg);// 获取共享锁protectedbooleantryReleaseShared(intarg);// 释放共享锁// 通用protectedbooleanisHeldExclusively();// 是否被独占5. 队列节点Node状态状态值含义CANCELLED1节点被取消超时或中断SIGNAL-1后继节点需要被唤醒CONDITION-2在 Condition 队列中PROPAGATE-3共享模式传播6. 获取锁的流程以 ReentrantLock 为例7. 核心源码分析// AQS 获取锁的入口publicfinalvoidacquire(intarg){if(!tryAcquire(arg)// 1. 快速尝试获取acquireQueued(addWaiter(Node.EXCLUSIVE),arg))// 2. 入队 排队获取selfInterrupt();// 3. 恢复中断状态}// 入队操作CAS 保证线程安全privateNodeaddWaiter(Nodemode){NodenodenewNode(Thread.currentThread(),mode);Nodepredtail;if(pred!null){node.prevpred;if(compareAndSetTail(pred,node)){// CAS 入队pred.nextnode;returnnode;}}enq(node);// 初始化或重试returnnode;}8. AQS 应用同步器模式用途ReentrantLock独占可重入互斥锁ReentrantReadWriteLock独占共享读写分离锁Semaphore共享限流/资源池CountDownLatch共享等待多线程完成CyclicBarrier共享线程互相等待Phaser共享分阶段任务三、CAS vs AQS维度CASAQS层级底层原子操作上层同步框架机制乐观锁无锁悲观锁 队列适用场景简单变量更新复杂同步控制线程冲突重试自旋阻塞 park/unpark CPU 消耗高冲突时较高阻塞后较低关系AQS 内部用 CAS 维护 state 和队列四、实际应用1. 基于 CAS 的原子计数器AtomicIntegercounternewAtomicInteger(0);// 底层CAS 循环直到成功counter.incrementAndGet();基于 AQS 的自定义锁classSimpleLockextendsAbstractQueuedSynchronizer{OverrideprotectedbooleantryAcquire(intarg){returncompareAndSetState(0,1);// CAS 修改 state}OverrideprotectedbooleantryRelease(intarg){setState(0);returntrue;}publicvoidlock(){acquire(1);}publicvoidunlock(){release(1);}}五、总结CAS 是 Java 实现无锁并发的底层利器适用于低竞争、简单场景AQS 是构建复杂同步器的框架通过 state CLH 队列 CAS 实现了高效的线程阻塞与唤醒两者相辅相成AQS 内部大量依赖 CAS 操作如 compareAndSetState、compareAndSetTail