CAS不直接实现状态机,而是通过原子类(如AtomicInteger)循环CAS更新volatile状态字段,配合显式状态定义、合法转移规则和条件校验,构建无锁、一致、可观测的轻量级状态机。

CAS(Compare-And-Swap)本身不直接实现“状态机”,而是提供一种原子的、无锁的变量更新能力;在高并发下构建无锁状态机,核心是**用 CAS 循环尝试修改状态字段,配合显式状态定义和合法转移规则**,避免锁竞争的同时保证状态一致性。
状态字段必须是 volatile + 原子类型
状态不能用普通 int 或枚举变量,否则读写不可见或非原子。必须使用 AtomicInteger、AtomicReference<StateEnum> 等原子类,并确保状态值本身不可变(如用 enum 或 final 类封装)。
- 推荐用 AtomicInteger 存储状态码(如 0=INIT, 1=RUNNING, 2=STOPPED),比对象引用 CAS 更轻量
- 若状态含数据(如带时间戳、版本号),可用 AtomicStampedReference 避免 ABA 问题
- 所有状态读取必须通过 get(),禁止缓存本地副本
状态转移必须用 CAS 循环 + 显式校验
不能直接 set 新状态,而要循环判断当前状态是否符合转移前提,再 CAS 更新。例如:只允许从 RUNNING → STOPPED,不允许 INIT → STOPPED。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 写法模板:while (true) { int expect = state.get(); if (expect == RUNNING && state.compareAndSet(RUNNING, STOPPED)) break; }
- 若需多条件(如“仅当状态为 RUNNING 且 pendingCount == 0 时才能停止”),把条件检查放在 CAS 外,失败则重试或退避
- 避免无限空转,可加 Thread.onSpinWait()(JDK9+)或短延时提升 CPU 效率
状态机逻辑与业务解耦,用函数式风格封装转移
把每个状态转移抽象成独立方法(如 tryStart()、tryStop()),内部完成校验 + CAS + 后置动作(如唤醒监听器、清理资源),调用方只关心返回布尔值表示是否成功。
立即学习“Java免费学习笔记(深入)”;
- 返回 true 表示状态已按预期变更,业务可继续执行后续逻辑
- 返回 false 表示转移被拒绝(如当前状态不符),由上层决定重试、报错或降级
- 禁止在 CAS 成功后做耗时操作(如 I/O、复杂计算),否则阻塞其他线程的 CAS 尝试
注意边界与可观测性
无锁不等于无问题。需主动处理异常路径和监控缺失:
- 记录非法状态跃迁(如日志中发现从 STOPPED 直接跳到 RUNNING),说明业务逻辑有漏洞
- 暴露当前状态的只读 getter(如 getState()),供监控系统采集,不要暴露 setter
- 必要时引入版本号或时间戳字段,配合 CAS 实现带序状态变更(如“只接受比当前时间戳更新的状态”)

















