这个问题不涉及于竞态条件、原子性或者为什么你应该在代码中使用锁。我已经了解了这些。
更新:我的问题不是“易失性内存存在奇怪的情况”(我知道它存在),我的问题是“.NET运行时是否将其抽象化,使您永远不会看到它”。
请参见http://www.yoda.arachsys.com/csharp/threads/volatility.shtml和“字符串属性本身是否线程安全?”上的第一个答案。
(它们实际上是相同的一篇文章,因为其中一篇引用了另一篇。)一个线程设置一个布尔值,另一个线程无限循环读取该布尔值--这些文章声称读取线程可能会缓存旧值并且永远不会读取新值,因此你需要一个锁(或使用volatile关键字)。他们声称以下代码可能会无限循环。 现在我同意锁定变量是个好习惯,但我不能相信.NET运行时真的会像文章所声称的那样忽略内存值的更改。我理解他们关于易失性内存与非易失性内存的讨论,并且我同意在非管理代码中他们有一个有效的观点,但是我不能相信.NET运行时不会正确地将其抽象化,以使以下代码实现您期望的功能。 该文章甚至承认该代码将“几乎肯定”能够工作(虽然不能保证),所以我对这个说法提出质疑。有人能否验证以下代码不总是有效?有人能否得到即使一种情况(也许您无法始终复制它)导致它失败的情况?
class BackgroundTaskDemo
{
private bool stopping = false;
static void Main()
{
BackgroundTaskDemo demo = new BackgroundTaskDemo();
new Thread(demo.DoWork).Start();
Thread.Sleep(5000);
demo.stopping = true;
}
static void DoWork()
{
while (!stopping)
{
// Do something here
}
}
}