竞态条件(race condition)指多个线程/进程并发访问共享数据,且至少一个是写操作时,程序结果依赖于它们执行的交错顺序,导致结果不确定、可能出错。

经典例子:两个线程同时对共享计数器执行 count++,初始为 0,期望结果是 2,但实际可能得到 1。因为 count++ 不是原子操作,它拆成三步:读取、加一、写回。若两个线程都先读到 0,各自加一后都写回 1,就丢了一次更新。

// 线程 A 和 B 并发执行,count 初值为 0
count++;  // 实际是: tmp = count; tmp = tmp + 1; count = tmp;
// 交错顺序: A读0 → B读0 → A写1 → B写1 → 结果为1(错误)

展开解析:发生竞态的前提是有共享可变状态 + 非原子的"检查-再操作"序列。常见变体:check-then-act(如单例的 if (instance == null))、read-modify-write(上面的自增)。

解决思路:加互斥锁让临界区串行化;用原子操作(CAS、AtomicInteger 等);或从设计上消除共享(线程封闭、不可变对象、消息传递)。

易错点:单核 CPU 同样会有竞态——线程切换可能发生在任意两条指令之间;加 volatile 只保证可见性,不保证原子性。

追问方向:数据竞争与竞态条件的区别、ABA 问题。