synchronized性能需分场景对比:低竞争(4–8线程)看自旋稳定性,中高竞争(16线程)观察锁膨胀与耗时跳变,强竞争(32+线程)关注blocked时间与吞吐断崖;必须对照空方法、volatile、atomicinteger测试,jmh需配置fork、warmup、measurement及禁用逃逸分析,指标重点关注throughput和stdev。

明确三类高并发场景
高并发不是线程越多越好,要分层设计测试用例:
- 低竞争(4–8 线程):模拟常见服务端请求,线程交替进入临界区,重点看轻量级锁自旋是否稳定,延迟是否小幅上升
- 中高竞争(16 线程):触发偏向锁撤销和轻量级锁膨胀,观察 monitor 进入/退出耗时是否跳变、stdev(标准差)是否显著增大
- 强竞争(32+ 线程):逼近重量级锁阈值,关注线程 BLOCKED 时间、上下文切换次数、吞吐量断崖式下降点
必须配对照组,不能只跑 synchronized
单独一个 `@Benchmark` 方法毫无参考价值。至少并列测试以下四组,操作逻辑完全一致(如都对同一计数器做 +1):
- 空方法调用(baseline):扣除 JVM 方法调用本身开销
-
volatile int写+读:仅验证可见性,无互斥成本 -
AtomicInteger.incrementAndGet():CAS 原子操作,现代常用替代方案 -
synchronized(this) { count++; }:目标同步块,锁对象、字段访问方式、循环体内容与前三者严格对齐
JMH 关键配置不能省
默认配置会严重污染结果,尤其在高并发下:
-
@Fork(3):至少 3 个独立 JVM 进程,避免 GC 或 JIT 残留状态串扰 -
@Warmup(iterations = 10, time = 5, timeUnit = TimeUnit.SECONDS):充分预热,让偏向锁建立→撤销→升级过程走完,JIT 编译稳定 -
@Measurement(iterations = 10, time = 5, timeUnit = TimeUnit.SECONDS):长时采样,压制 CPU 频率抖动和瞬时 GC 干扰 -
@State(Scope.Benchmark):共享被测对象(如单例计数器),确保真实竞争;禁用Scope.Thread - JVM 参数加
-XX:-DoEscapeAnalysis -XX:+UnlockDiagnosticVMOptions -XX:+PrintSafepointStatistics:关闭逃逸分析干扰,同时捕获 safepoint 停顿影响
看指标要盯住两个核心维度
高并发下不能只看平均值:
- Throughput(ops/s):单位时间完成操作数。synchronized 在 32 线程下可能比 AtomicInteger 低 3–7 倍——这不是“慢”,是锁争用导致有效工作时间占比骤降
-
AverageTime(ns/op) + stdev:若 stdev 超过均值 50%,说明大量线程在 BLOCKED 状态等待,已出现明显调度瓶颈;此时需结合
jstack或 JFR 查看线程栈中java.lang.Thread.State: BLOCKED (on object monitor)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











