C#中Interlocked.Exchange的作用

在 C# 中,**Interlocked.Exchange**是一个用于 多线程原子操作 的关键方法,其核心作用是 以线程安全的方式交换变量的值。以下是它的详细说明:

核心作用

原子性操作 :

在无锁(lock-free)的多线程编程中,Interlocked.Exchange 能够确保以下两个操作作为一个 不可分割的原子操作 完成:

  1. 读取 变量的当前值

  2. 写入 新值到该变量

这避免了线程竞争(Race Condition)导致的数据不一致问题。

方法签名

cs 复制代码
public static T Exchange<T>(ref T location, T value) where T : class;
public static int Exchange(ref int location, int value);
// 其他重载支持 long、float、double 等类型
  • 输入 :通过 ref 传递的变量引用(location)和新值(value)。

  • 输出 :返回变量被修改前的 原始值。

典型使用场景

  1. 线程安全的标志位切换

    cs 复制代码
    private bool _isRunning;
    
    public void Stop()
    {
        // 原子性地将 _isRunning 设为 false,并返回之前的值
        bool original = Interlocked.Exchange(ref _isRunning, false);
        if (original)
        {
            Console.WriteLine("成功停止");
        }
    }
  2. 无锁编程中的状态更新

    cs 复制代码
    private object _currentData;
    
    public void UpdateData(object newData)
    {
        // 原子性替换数据,并获取旧数据以进行清理
        object oldData = Interlocked.Exchange(ref _currentData, newData);
        if (oldData != null)
        {
            Cleanup(oldData);
        }
    }
  3. 单次初始化(如单例模式)

    cs 复制代码
    private object _singletonInstance;
    private readonly object _lock = new object();
    
    public object GetInstance()
    {
        if (_singletonInstance == null)
        {
            var temp = new object();
            // 原子性竞争创建实例
            Interlocked.CompareExchange(ref _singletonInstance, temp, null);
        }
        return _singletonInstance;
    }

性能优势

  • 避免锁开销 :与 lock 语句相比,Interlocked 类的方法直接利用 CPU 的原子指令(如 x86 的 XCHG),无需上下文切换或阻塞线程。

  • 轻量级 :适合高频调用的简单操作。

注意事项

  1. 适用范围 :仅适用于简单的值替换操作,复杂逻辑需结合 Interlocked.CompareExchange 或锁。

  2. 引用类型 :泛型版本 (Interlocked.Exchange<T>) 支持引用类型,但需注意内存可见性问题(可通过 volatile 关键字或内存屏障解决)。

相关推荐
Dwzun11 分钟前
基于SpringBoot3+Vue3的油莎豆种植管理系统
java·前端·vue.js·spring boot·后端·python·计算机网络
学长毕设9 小时前
基于SpringBoot的实验室资产管理系统
java·spring boot·后端
她说可以呀10 小时前
Vue插槽
前端·javascript·vue.js
qq_4480111610 小时前
Vue + Jinja2两套模版与法冲突造成undefinedError
前端·javascript·vue.js
zzu123zsw10 小时前
从臃肿的模板调用到声明式契约:深入 UniHttp 动态代理与多渠道生命周期扩展
java·spring boot·microsoft·unihttp
源码集结号11 小时前
云诊所门诊系统源码,基于SpringBoot+Vue.js架构,支持多租户设计与Docker容器化部署
java·spring boot·源码·医院信息系统·门诊系统·诊所系统
论文复现现场11 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
啃瓜子的松鼠11 小时前
泛微OAe9-后端二开异步调用
java
FRing0312 小时前
JavaScript入门到精通三十二(深拷贝、浅拷贝、递归函数)
开发语言·前端·javascript
秋天的怀念_David12 小时前
第二十一夜 · 数字黑洞与西西弗斯的惩罚
java·程序人生·算法