CPU密集型工作场景下调用Thread.onSpinWait()是否存在收益?
结论
你的使用场景完全不适合Thread.onSpinWait(),当前观察到的性能损耗是意料之中的结果。
具体说明
- 设计目的与底层实现
Thread.onSpinWait()在x86平台的主流JVM实现中,会被编译为CPU的pause指令,它的设计初衷仅面向自旋等待场景:也就是线程处于忙等状态,循环中没有任何有效计算,只是在等待其他线程修改某个共享变量的状态(比如自旋锁的解锁操作)。
对应官方文档的描述就是「调用方暂时无法推进执行,需要等待其他活动触发操作后才能继续」,你的素数计算循环完全不满足这个前提——每一轮循环都在执行
divisor的递增、取模运算,都是有效计算任务,不需要等待任何外部线程的操作。
性能损耗的原因
pause指令本身会让CPU流水线暂停几十到上百个时钟周期,你在每一轮素数校验循环中都插入这个调用,等于主动给计算逻辑插入固定延迟,出现明显的性能下降是必然结果。对其他线程的收益说明
唯一可能的收益仅存在于开启超线程的CPU场景下:当你的计算线程和另一个线程共享同一个物理核心的两个超线程逻辑核心时,pause指令会让当前逻辑核心暂时让出一部分执行资源给同核心的另一个线程,让它获得更多执行机会。但这个收益的不确定性极高:
- 如果当前物理核心上没有其他线程在运行,
pause带来的延迟就是纯性能浪费,没有任何正面收益 - 这个操作不会修改操作系统层面的线程优先级,也不会主动将线程调度到后台,影响范围仅局限于当前物理核心的超线程 sibling,无法实现全局的资源让出
- 如果你确实需要降低计算线程对其他业务线程的影响,直接通过
Thread.setPriority()调整线程优先级是更可靠、可预期的实现方式,完全不需要通过Thread.onSpinWait()来实现
优化建议
你给出的素数校验逻辑中直接删除Thread.onSpinWait()调用即可,这个调用在当前场景下没有任何价值,只会带来不必要的性能损耗。
内容的提问来源于stack exchange,提问作者Eric Kolotyluk
相关产品推荐
相关产品推荐

