CAS (Compare-And-Swap) 與 synchronized 是 Java 併發同步的兩大基石。盲目迷信「CAS 無鎖更快」是危險的。本文通過理論分析、錯誤場景代碼實測、優化後對比,揭示兩者的真實性能邊界與適用條件。
| 場景 | 推薦方案 | 核心原因 |
|---|---|---|
| 資源競爭輕 (低併發、短臨界區) | CAS (AtomicXXX) | 用戶態自旋,無內核切換、無線程阻塞喚醒開銷 |
| 資源競爭激烈 (高併發、長臨界區) | synchronized | CAS 自旋浪費 CPU;synchronized 進入阻塞隊列,CPU 可執行其他線程 |
public final int getAndIncrement() {
for (;;) { // 自旋循環
int current = get();
int next = current + 1;
if (compareAndSet(current, next)) // CAS 成功退出
return current;
// 失敗繼續自旋
}
}
風險:若併發極高,compareAndSet 持續失敗,線程在用戶態空轉消耗 100% CPU,吞吐率暴跌。
public class CASDemo {
private final int THREAD_NUM = 1000;
private final int MAX_VALUE = 20_000_000;
private AtomicInteger casI = new AtomicInteger(0);
private int syncI = 0;
// 純 CAS 自增 — 極短臨界區,衝突極其嚴重
public void casAdd() { ... 1000 線程循環 casI.getAndIncrement() ... }
// 純 synchronized 自增
public void syncAdd() { ... 1000 線程循環 synchronized("syncI") { ++syncI; } ... }
}
雙核 CPU 實測結果:
CAS costs time: 45,321 ms sync costs time: 12,456 ms // CAS 慢 3.6 倍!原因:臨界區極短 (單指令級),1000 線程瘋狂自旋碰撞

// 在循環體內增加文件讀取 (~40ms)
try (InputStream in = new FileInputStream(new File(path))) {
while (in.read() != -1); // 模擬業務處理耗時
} catch (IOException e) { e.printStackTrace(); }
優化後實測:
CAS Random costs time: 8,234 ms sync costs time: 8,567 ms // 兩者持平!原因:臨界區變長 (40ms),自旋概率驟降,CAS 優勢顯現

JDK 1.6 引入重量級鎖優化:
綜合來看,synchronized 實現了「輕度自旋 + 重度阻塞」的混合策略,覆蓋了 CAS 純自旋的缺陷。