众所周知,与Java的易失性不同,.NET的版本允许使用来自另一个位置的以下易失性读取来重新排序易失性写入.当它是一个问题时 MemoryBarier,建议放在它们之间,或者Interlocked.Exchange可以用来代替volatile写.
它可以工作,但MemoryBarier在高度优化的无锁代码中使用时可能成为性能杀手.
我想了一下,想出了一个主意.我希望有人告诉我,我是否采取了正确的方式.
所以,这个想法如下:
我们希望防止这两种访问之间的重新排序:
volatile1 write
volatile2 read
Run Code Online (Sandbox Code Playgroud)
从.NET MM我们知道:
1) writes to a variable cannot be reordered with a following read from
the same variable
2) no volatile accesses can be eliminated
3) no memory accesses can be reordered with a previous volatile read
Run Code Online (Sandbox Code Playgroud)
为了防止写入和读取之间不必要的重新排序,我们从刚刚写入的变量中引入了一个虚拟易失性读取:
A) volatile1 write
B) volatile1 read [to a visible (accessible | potentially shared) location]
C) volatile2 read
Run Code Online (Sandbox Code Playgroud)
在这种情况下,B不能用A重新排序,因为它们都访问相同的变量, C不能用B重新排序,因为两个易失性读取不能相互重新排序,并且传递C …