JMH是量化synchronized性能开销的可靠工具,需区分单线程无竞争、多线程低竞争和高竞争三类场景,设置合理预热与测量轮次,构造含对照组的可比基准,并关注吞吐量、平均响应时间及P99等关键指标。

Java 中 synchronized 锁的性能基准测试不能靠简单写个循环、测个耗时来下结论——JVM 的锁优化(如偏向锁、轻量级锁)、预热不足、线程调度干扰都会让结果失真。真正可靠的测试必须用专业工具、控制变量、区分场景。
用 JMH 做标准化基准测试
JMH(Java Microbenchmark Harness)是 Oracle 官方推荐的微基准测试框架,它能自动处理 JVM 预热、GC 干扰、统计抖动等问题,避免手工测试常见陷阱。
- 设置合理的预热轮次(如
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS))和测量轮次(如@Measurement(iterations = 10)) - 使用
@Fork(jvmArgsAppend = "-XX:+UseBiasedLocking")显式开启/关闭特定锁优化,做对比实验 - 固定线程数(
@Threads(4))和作用域(@State(Scope.Benchmark)),确保共享资源状态一致
设计可比、真实的测试场景
不要只测空同步块,要模拟典型临界区行为:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 用一个带简单计算的共享计数器(如
volatile int counter+ 自增逻辑),避免被 JIT 优化掉 - 对比相同逻辑:synchronized 方法 vs. ReentrantLock.lock()/unlock() vs. StampedLock.writeLock()
- 分三类负载测试:低竞争(2–4 线程)、中等竞争(8–16 线程)、高竞争(32+ 线程)
- 加入读写比例变量:例如 9:1 读写比下,再测 synchronized vs. ReadWriteLock vs. StampedLock 乐观读
关注关键指标,不止看平均值
单看“平均耗时”容易误判,尤其在高争用下尾部延迟(P99/P999)更关键:
立即学习“Java免费学习笔记(深入)”;
- 吞吐量(ops/s):单位时间完成的操作数,反映整体并发能力
- 平均响应时间(ns/op):基础参考,但需结合分布看
- 百分位延迟(P90/P99):高争用下,synchronized 可能平均快,但 P99 明显毛刺更多
- GC 压力与线程阻塞态占比:用 JFR 或 async-profiler 采集,判断是否因锁导致频繁上下文切换
排除干扰,验证 JVM 行为
确认实际生效的锁机制,而不是假设:
- 加 JVM 参数
-XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly(需 hsdis)观察锁膨胀过程 - 用
jstack或 JFR 查看线程是否长期处于BLOCKED或WAITING状态 - 禁用偏向锁(
-XX:-UseBiasedLocking)后重测,观察性能变化幅度——若下降明显,说明原场景受益于偏向锁


















