公共十进制属性是线程安全的

本文关键字:线程 安全 属性 十进制 | 更新日期: 2023-09-27 18:18:52

我有一个类,它有一个可以从多个线程访问的十进制属性

public class MyObject
{
    public decimal MyProperty{get; set;}
}

我应该在get &准备好了吗?我知道decimal不是使用原子运算的类型,decimal使用96位。

但是,只为这些类型编写锁感觉非常尴尬——特别是当您不完全确定为什么要这样做时。

公共十进制属性是线程安全的

不,对小数的操作不是原子性的。

CLR只保证读写32位值和引用大小的值的原子性。十进制由多个32位整数组成,因此对其进行的操作不是原子性的。


但是通常属性不需要是线程安全的。通常你在更高的层次上使用锁,在那里代码更清楚你需要什么样的锁。

即使你在属性getter和setter中使用了锁,像MyProperty+=1这样的简单操作也不是线程安全的。

如果你在 MyObject的同一个实例上从不同的线程读写属性,那么是的,你需要同步访问属性。如果你使用不同的实例,它将是安全的,因为每个线程得到一个不同的实例。这取决于你的场景

From MSDN:

谨慎

分配这种类型的实例不是所有的线程安全的硬件平台,因为二进制表示的那个实例可能太大,无法在单个原子操作中赋值。

如果你只是需要避免撕裂读/写,那么答案是肯定的-你的代码将工作,因为CLR自动对齐这些属性在右边界(在这种情况下为8),除非你使用任何StructLayout(LayoutKind.Explicit)或[FieldOffset(…)]属性。

如果需要对属性进行更复杂的操作(如读和写),则可以使用任何互锁结构。看看互锁的任何图案(ru)。