我通常会编写这些代码:
public class MyClass
{
static bool m_stop = false;
public static void Main()
{
var th = new Thread(DoStuff);
th.Start();
Console.ReadLine();
m_stop = true;
th.Join();
}
private static void DoStuff()
{
while( !m_stop )
{
// do things here
}
}
}
...我总是同步访问变量m_stop,只是出于习惯。我想知道是否真的有必要这样做(假设在DoStuff()中运行一个或两个额外的循环不会伤害任何东西)。如果代码执行完全像这样可能会发生什么?我已经想到了为m_stop使用volatile关键字,但我不确定即使这是必要的。有人知道吗?
答案 0 :(得分:4)
没有易失性且没有任何同步,您显示的代码不是线程安全的。一个线程可以更改变量的值,另一个线程可能从不看到它,永远循环。如果您使用公共锁同步对它的所有访问,则 是线程安全的。
现在波动性是一个棘手的话题 - 我认为直到最近才理解它,但它doesn't mean quite what I thought it did。但是,我很确定只要使变量volatile可以满足您的需要。
对于更复杂的事情,我通常会使用完全同步:每次访问共享数据时都要锁定。
答案 1 :(得分:1)
虽然这种方法没有技术上错误,但是当您的应用程序需要扩展时,您可能会遇到麻烦。如果您正在同步访问它,也不需要使m_stop
易失。
答案 2 :(得分:0)
更新 m_stop 时必须放置内存屏障。因此,您必须将其标记为易失性(或自行放置内存屏障/易失性读写)