为了实现一个多线程应用的无锁代码,我使用了
但是,我在一本《C# 4.0 in a Nutshell》的书中读到,这是不正确的,因为
volatile
变量。
从理论上讲,volatile
关键字被简单地用于确保所有线程看到volatile
变量的最新值;所以如果线程A
更新了变量的值,而线程B
在这次更新后读取了该变量,它将看到最近由线程A写入的最新值。但是,我在一本《C# 4.0 in a Nutshell》的书中读到,这是不正确的,因为
应用volatile不能防止写入后紧接着的读取被交换。这个问题可以通过在每次获取
volatile
变量之前放置Thread.MemoryBarrier()
来解决吗?private volatile bool _foo = false;
private void A()
{
//…
Thread.MemoryBarrier();
if (_foo)
{
//do somthing
}
}
private void B()
{
//…
_foo = true;
//…
}
如果这解决了问题,考虑我们有一个 while 循环依赖于其条件中的该值;那么在 while 循环之前放置 Thread.MemoryBarrier()
是否是修复此问题的正确方法?例如:
private void A()
{
Thread.MemoryBarrier();
while (_someOtherConditions && _foo)
{
// do somthing.
}
}
为了更加准确,我希望在任何时候,任何线程请求它时,_foo
变量都能给出其最新值;所以如果在调用变量之前插入Thread.MemoryBarrier()
可以解决问题,那么我能否使用Foo
属性代替_foo
,并在该属性的get中执行Thread.MemoryBarrier()
,像这样:
Foo
{
get
{
Thread.MemoryBarrier();
return _foo;
}
set
{
_foo = value;
}
}