联锁和易变

我有一个variables,我用来代表状态。 它可以从多个线程读取和写入。

我正在使用Interlocked.ExchangeInterlocked.CompareExchange来更改它。 不过,我正在从多个线程阅读它。

我知道volatile可以用来确保variables不被本地caching,但是总是直接从内存中读取。

但是,如果我将该variables设置为volatile,那么它会生成关于使用volatile的警告,并将ref传递给Interlocked方法。

我想确保每个线程正在读取variables的最新值,而不是一些caching版本,但我不能使用volatile。

有一个Interlocked.Read但它是64位types,并不是在紧凑的框架。 它的文档说,它是不需要的32位types,因为它们已经在一个单一的操作中执行。

在互联网上发表的声明表明,如果您使用互锁方法进行所有访问,则不需要变化。 但是,您无法使用联锁方法读取32位variables,因此您无法使用联锁方法进行所有访问。

有没有办法实现线程安全读写我的variables,而不使用locking?

当您使用Interlocked.Xxx函数时(请参阅此问题 ),您可以安全地忽略该警告,因为它们总是执行易失性操作。 所以一个volatilevariables对共享状态来说是完全可以的。 如果你不惜一切代价摆脱这个警告,你实际上可以Interlocked.CompareExchange (ref counter, 0, 0)做一个互锁读取。

编辑:实际上, 只有在您要直接写入状态variables(即不使用Interlocked.Xxx )时, 需要状态variables的variables。 正如jerryjvl提到的那样 ,读取一个用互锁(或易失)操作更新的variables将使用最近的值。

互锁操作和易失性不是真的应该同时使用。 你得到一个警告的原因是因为它(几乎?)总是表示你误解了你在做什么。

过度简化和解释:
volatile指示每个读取操作需要从内存中重新读取,因为可能有其他线程正在更新variables。 当应用于一个可以通过你正在运行的体系结构primefaces读取/写入的字段时,除非你使用long / ulong,否则这应该是你所需要做的,大多数其他types可以被primefaces读取/写入。

当一个字段没有被标记为volatile时,你可以使用Interlocked操作来做出类似的保证,因为它会导致caching被刷新,这样更新对所有其他处理器都是可见的。这样做的好处是可以把开销在更新而不是读取。

这两种方法哪一种最好取决于你在做什么。 这个解释是过分简化的。 但是从这个angular度应该可以看出,同时做这两件事是毫无意义的。