有人能很好地解释一下c#中的volatile关键字吗?它能解决哪些问题,不能解决哪些问题?在哪些情况下,它将节省我使用锁定?


当前回答

综上所述,这个问题的正确答案是: 如果代码在2.0运行时或更高版本中运行,volatile关键字几乎不需要,如果不必要地使用,弊大于利。也就是说,永远不要用它。但是在运行时的早期版本中,需要对静态字段进行适当的双重检查锁定。特别是具有静态类初始化代码的静态字段。

其他回答

多个线程可以访问一个变量。 最新的更新将在变量上

我发现Joydip Kanjilal的这篇文章非常有用!

当您将一个对象或变量标记为volatile时,它将成为volatile读写的候选对象。需要注意的是,在c#中,所有的内存写操作都是volatile的,不管你写的是volatile对象还是非volatile对象。但是,当读取数据时,就会出现这种不确定性。当读取非易失性数据时,执行线程可能总是获得最新的值,也可能不总是。如果对象是volatile,线程总是获得最新的值

我就把它放在这里,供大家参考

有时候,编译器会优化一个字段并使用寄存器来存储它。如果线程1写了字段,而另一个线程访问了它,因为更新存储在寄存器(而不是内存)中,第二个线程将得到陈旧的数据。

你可以把volatile关键字看作是对编译器说“我想让你把这个值存储在内存中”。这保证了第二个线程检索到最新的值。

CLR喜欢优化指令,所以当你在代码中访问一个字段时,它可能并不总是访问该字段的当前值(它可能来自堆栈等)。将字段标记为volatile可以确保该指令可以访问该字段的当前值。当程序中的并发线程或操作系统中运行的其他代码可以修改该值(在非锁定场景中)时,这很有用。

您显然失去了一些优化,但它确实使代码更加简单。

综上所述,这个问题的正确答案是: 如果代码在2.0运行时或更高版本中运行,volatile关键字几乎不需要,如果不必要地使用,弊大于利。也就是说,永远不要用它。但是在运行时的早期版本中,需要对静态字段进行适当的双重检查锁定。特别是具有静态类初始化代码的静态字段。