C# 公共十进制属性是线程安全的吗?
我有一个类,它有一个可以从多个线程访问的十进制属性C# 公共十进制属性是线程安全的吗?,c#,.net,multithreading,C#,.net,Multithreading,我有一个类,它有一个可以从多个线程访问的十进制属性 public class MyObject { public decimal MyProperty{get; set;} } 我应该在get&set内部使用锁吗? 我知道十进制不是原子运算的类型,十进制使用96位 只为这类类型编写锁会让人感觉非常尴尬,尤其是当您不完全确定为什么要这样做时。不,十进制操作不是原子操作 CLR仅保证读取/写入32位值和参考大小值的原子性。十进制由多个32位整数组成,因此对它的操作不是原子的 但通常属性不
public class MyObject
{
public decimal MyProperty{get; set;}
}
我应该在get&set内部使用锁吗?
我知道十进制不是原子运算的类型,十进制使用96位
只为这类类型编写锁会让人感觉非常尴尬,尤其是当您不完全确定为什么要这样做时。不,十进制操作不是原子操作 CLR仅保证读取/写入32位值和参考大小值的原子性。十进制由多个32位整数组成,因此对它的操作不是原子的
但通常属性不需要是线程安全的。通常,您在更高的级别上使用锁定,代码更了解您需要什么样的锁定
即使在属性getter和setter中使用锁定,像
MyProperty+=1
这样的简单操作也不会是线程安全的。如果您在同一个MyObject实例上从不同线程写入和读取属性,那么,是的,您需要同步对该属性的访问。如果您使用不同的实例,它将是安全的,因为每个线程都会获得不同的实例。这将真正取决于您的场景。来自:
谨慎
分配此类型的实例在所有情况下都不是线程安全的
硬件平台,因为该实例的二进制表示形式
可能太大,无法在单个原子操作中分配
如果您只需要避免,那么答案是肯定的-您的代码将起作用,因为CLR会自动将这些属性对齐到正确的边界(在本例中为8),除非您使用或属性中的任何一个
如果需要对属性执行更复杂的操作(如读取和写入),则可以使用任何构造。再看一下(ru)。如果我只从一个线程设置属性,从多个线程获取?@gordava,如果这发生在同一个实例上,那么这不是线程安全的,需要同步。两个线程写入一个
十进制
可能导致一个“断开”值,结果值是两次写入的混合。哎呀,你说得对——我写上面的答案时正在考虑加倍!在32位系统上,即使对Double
s或Int64
s的写入也不能保证是原子的。