我已经阅读了一些关于volatile
关键字和没有使用该关键字时的行为的帖子。
我特别测试了在C#中说明使用volatile关键字的用法答案中的代码。当运行时,在Release模式下,没有调试器连接时,我观察到了期望的行为。到那个时候,没有问题。
因此,就我所理解的而言,以下代码应该永远不会退出。
public class Program
{
private bool stopThread;
public void Test()
{
while (!stopThread) { } // Read stopThread which is not marked as volatile
Console.WriteLine("Stopped.");
}
private static void Main()
{
Program program = new Program();
Thread thread = new Thread(program.Test);
thread.Start();
Console.WriteLine("Press a key to stop the thread.");
Console.ReadKey();
Console.WriteLine("Waiting for thread.");
program.stopThread = true;
thread.Join(); // Waits for the thread to stop.
}
}
为什么它会出现?即使在没有调试器的情况下,也是如此。
更新
从说明C#中使用volatile关键字的用法的代码进行了适应。
private bool exit;
public void Test()
{
Thread.Sleep(500);
exit = true;
Console.WriteLine("Exit requested.");
}
private static void Main()
{
Program program = new Program();
// Starts the thread
Thread thread = new Thread(program.Test);
thread.Start();
Console.WriteLine("Waiting for thread.");
while (!program.exit) { }
}
在Release模式下,没有调试器附加时,该程序不会退出。
stopThread
在循环内部没有被更改,因此可以自由地假设它要么永远循环,要么根本不循环。在这种语言中,编译器不必在每次迭代中重新读取它,因此可能不会注意到另一个线程已经更改了它。我不确定CLR/.net在这种情况下的保证。 - CodesInChaos