单线程环境下AtomicInteger与同步计数器JMH测试结果合理性疑问
单线程下AtomicInteger与synchronized计数器性能测试的有效性验证
你的JMH基准测试实现是正确的,测试结果真实有效,具体分析如下:
测试代码的正确性
- 状态类使用
@State(Scope.Benchmark)注解,确保计数器实例在整个基准测试周期内稳定存在,单线程场景下不会出现重复初始化的问题。 - 通过
Blackhole.consume接收自增操作的返回值,避免JIT编译器因检测不到操作的副作用而将其优化消除,保证测试数据的准确性。 - 预热轮次、测量轮次以及单线程的配置均符合JMH的标准用法,能够有效消除JIT编译、缓存加载等因素对测试结果的干扰。
性能差异的核心原因
在单线程无竞争的场景中:
- AtomicInteger的
incrementAndGet方法基于硬件原生的CAS(Compare-And-Swap)指令实现原子操作。由于没有线程竞争,CAS操作一次即可成功,仅需执行少量内存屏障和寄存器交互,整体开销极低。 - synchronized计数器虽然会触发JVM的偏向锁优化(避免重量级锁的高昂开销),但仍需执行偏向锁标记检查、线程ID匹配等逻辑,再加上
synchronized块自带的内存屏障,整体操作的开销要略高于CAS。即使counter变量被声明为volatile,同步方法为保证原子性带来的锁相关额外操作,还是会导致其吞吐量低于AtomicInteger。
结果合理性验证
单线程下AtomicInteger达到1.45亿次/秒的吞吐量,而synchronized计数器约1亿次/秒,这个差异完全符合预期。无竞争场景下,硬件原生支持的CAS操作比JVM层面优化的偏向锁拥有更优的性能表现。
内容的提问来源于stack exchange,提问作者Kurkazawar
相关产品推荐
相关产品推荐

