我尝试了解 volatile 在多线程上下文中的使用。在以下代码中 another source of knowledge在互联网上:
class Program
{
static string _result;
//static volatile bool _done;
static bool _done;
static void SetVolatile()
{
// Set the string.
_result = "Dot Net Perls";
// The volatile field must be set at the end of this method.
_done = true;
}
static void Main()
{
// Run the above method on a new thread.
new Thread(new ThreadStart(SetVolatile)).Start();
// Wait a while.
Thread.Sleep(200);
// Read the volatile field.
if (_done)
{
Console.WriteLine(_result);
}
}
}
volatile 关键字的演示使用应防止线程读取存储在缓存中的值。相反,它应该检查实际值。
因此,如果没有 volatile 的 _done
,仍然应该有一个 false 值(从缓存中读取),并且 Console.WriteLine
语句不应被执行。
不幸的是,在调试/ Release模式下运行此代码而不使用 volatile 关键字总是会产生输出。这个特定示例的要点是什么?
最佳答案
正如已经说过的,不使用 volatile 关键字并不意味着在所有情况下所有读取都需要缓存。它们可能被缓存,也可能没有。但如果您想要更多可重现的示例,请尝试以下操作:
class Program {
static string _result;
//static volatile bool _done;
static bool _done;
static void SetVolatile() {
// Set the string.
_result = "Dot Net Perls";
// The volatile field must be set at the end of this method.
_done = true;
}
static void Main() {
// Run the above method on a new thread.
new Thread(new ThreadStart(SetVolatile)).Start();
// prevent compiler to throw away empty while loop
// by doing something in it
int i = 0;
while (!_done) {
i++;
}
Console.WriteLine("done " + i);
}
}
在这里,您在 while 循环中重复读取 _done
,增加了它被缓存的可能性。程序应该以“done”消息终止,但不会,因为从另一个线程对 _done
的更改不会被注意到。
关于c# - 在标志字段上使用 volatile 关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47309012/