在Parallel.Invoke中并行更新同一对象的不同属性是否线程安全?
并行赋值同一对象不同属性的安全性解答
你提供的代码是安全的,不会给testResult对象带来线程安全问题,原因如下:
TestResult类的三个公开字段在内存中占据完全独立的存储位置,三个并行任务分别写入不同的内存地址,不存在竞态条件,不会出现写入互相覆盖、对象状态损坏的问题。- 即便属性为引用类型,单个引用赋值操作本身就是C#规定的原子操作,不会出现写入一半的中间状态,赋值过程本身是可靠的。
Parallel.Invoke方法会阻塞当前线程,直到所有传入的委托都执行完成,方法返回时所有属性的赋值操作都已经执行完毕,后续在当前线程读取属性值时,不会存在CPU缓存导致的内存可见性问题,一定能拿到最新的赋值结果。
注意事项
只要满足以下两个前提,该写法就可以长期稳定运行:
- 保证
GetProperty1Value()、GetProperty2Value()、GetProperty3Value()三个方法本身是线程安全的:如果这几个方法内部存在对共享可变状态的修改且没有做同步处理,会触发线程安全问题,但该问题和testResult对象的赋值操作无关。 - 如果你后续把公开字段修改为带
set访问器的属性,需要保证每个属性的set访问器内部仅对当前属性对应的私有字段赋值,没有修改类的其他共享状态,否则依然可能出现竞态条件。
该场景符合.NET官方线程安全基础规范:多个线程仅操作不同的独立变量时,不需要额外加同步机制,属于标准的无共享状态并行优化写法,可放心使用。
内容的提问来源于stack exchange,提问作者SRIDHARAN
相关产品推荐
相关产品推荐

