You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

线程安全读取int值:直接赋值与Interlocked.CompareExchange哪种可行?

多线程环境下int变量读取的线程安全性分析

1. 直接读取 int localSaved = counter; 的情况

32位int类型在x86/x64架构的CPU上,直接读取本身是原子操作——不会出现读到“半截值”的情况(比如只读到变量的高16位或者低16位)。但存在关键问题:这种读取没有内存可见性保证。

简单来说,如果其他线程刚修改了counter的值,当前线程可能因为CPU缓存、指令重排的原因,读到的是缓存里的旧值,而非内存里的最新值。所以如果你的场景要求必须拿到counter的最新状态,直接读取就不算完全线程安全。

2. 使用 Interlocked.CompareExchange(ref counter, 0, 0) 的情况

这种方式是完全线程安全的,既保证原子性,又保证内存可见性。

拆解Interlocked.CompareExchange的工作逻辑

Interlocked.CompareExchange 的核心流程很清晰:

  1. 先读取目标变量(也就是counter)的当前值
  2. 把这个值和第三个参数(这里是0)做对比
  3. 如果两者相等,就把第二个参数(这里是0)赋值给counter;如果不等,什么都不做
  4. 最后返回counter的原始值

你用到的 Interlocked.CompareExchange(ref counter, 0, 0),不管counter当前是什么值,除非它刚好是0(就算是0,赋值0也等于没修改),否则对比都不成立,所以本质上就是原子性地读取counter的最新值。而且Interlocked系列方法自带内存屏障,能保证读取到的是其他线程已经同步到内存的最新值,不会有缓存过期的问题。

总结

  • 直接读取:原子性没问题,但存在读取不到最新值的风险,不适合需要精准获取当前状态的多线程场景
  • Interlocked.CompareExchange读取:原子性和内存可见性都有保障,是安全的多线程读取方式

内容的提问来源于stack exchange,提问作者KeyKiller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 13:25:16