C#多线程:获取读锁是否必要?

35 浏览
0 Comments

C#多线程:获取读锁是否必要?

在多个线程中读取一个变量之前,是否有必要对该变量进行加锁?

admin 更改状态以发布 2023年5月21日
0
0 Comments

这取决于变量类型和您的平台。例如,在32位机器上读取Int64不保证具有原子性。因此,需要使用Interlocked.Read

0
0 Comments

简短的回答是:这取决于情况。

长的回答是:

  • 如果它不是共享值,即只有一个线程可以看到它(或使用它),则不需要任何同步。

  • 如果它是不可变值,即你只设置一次,然后只读取,那么在没有同步的情况下这样做是安全的(只要你在第一次写入完成之前不开始读取)。

  • 如果它是最多32位的"原始"类型(例如,byteshortint),在读取时可能会得到旧的数据。如果这没有影响,那么这样做就可以了。如果旧数据是不想要的,请使变量volatile来解决此问题。但是,如果有竞争的写入者,您需要像下面的long一样遵循相同的建议。

  • 如果它是超过32位的"原始"类型(例如,longdecimaldouble),您需要同步,否则您可能会读取一个值的"一半","另一个值的"一半",并得到疯狂的结果。为此,推荐的方法是使用Interlocked类的方法,进行读取和写入。

  • 如果它是引用类型,您需要同步以避免看到无效状态(Jeff Lamb的示例是一个很好的例子)。lock语句可能足够了。同样,您需要在读取和写入时锁定。

还有一些其他需要考虑的地方(例如锁定多长时间),但我认为这些已足以回答您的问题了。

0