我有下面的代码会产生不一致的输出。
string text = "t1";
new Thread ( () => Console.WriteLine (text) ).Start();
//Thread.Sleep(1);
text = "t2";
new Thread ( () => Console.WriteLine (text) ).Start();
有时会产生t1和t2,有时会产生双t2。 我现在在想的是那个。当它的输出是双t2时,第一个线程的捕获变量值是t2,因为它在最后一个变量赋值之后开始。我是对的吗?
注意:我在慢速机器上运行此代码。
答案 0 :(得分:3)
你是对的;请参阅维基百科上的race conditions。
根据定义,线程不会同步执行,因此您不应期望代码的顺序明确地确定程序的行为。
答案 1 :(得分:1)
是的,这是一个简单的多线程问题。
虽然第一个线程甚至没有启动,但您更改了文本变量的值。 然后第一个线程以新值开始,你有一个双't2'
答案 2 :(得分:1)
'有时它产生双t2'
在第一个
之前,文本的值已更改为“t2”new Thread ( () => Console.WriteLine (text) ).Start();
已执行
如果您想要一致性,请更改为:
string text = "t1";
new Thread ( () => Console.WriteLine (text) ).Start();
//Thread.Sleep(1);
string text2 = "t2";
new Thread ( () => Console.WriteLine (text2) ).Start();
答案 3 :(得分:1)
是的,每个人都提到你有种族条件。
在你的情况下,它暴露了大多数人一开始并不期望的闭包行为:闭包捕获变量,而不是它的值。这个问题可以在单线程案例中轻松显示:
string text = "t1";
Action a1 = () => Console.WriteLine (text);
a1(); // prints "t1"
text = "t2";
Action a2 = () => Console.WriteLine (text) ;
a1(); // prints "t2"
a2();
答案 4 :(得分:-1)
因此,最简单的方法是对变量
使用锁定这可以防止一个线程在被另一个线程使用时访问该变量