1

我有下面的代码产生不一致的输出。

string text = "t1";
new Thread ( () => Console.WriteLine (text) ).Start();

//Thread.Sleep(1);

text = "t2";
new Thread ( () => Console.WriteLine (text) ).Start();

有时它会产生 t1 和 t2,有时它会产生双倍的 t2。我现在在想的,是这样的。当它的输出为 double t2 时,第一个线程捕获的变量值为 t2,因为它是在最后一个变量赋值之后开始的。我对吗?

注意:我在慢速机器上运行此代码。

4

5 回答 5

3

你是对的; 在维基百科上查看比赛条件

根据定义,线程不会同步执行,因此您不应期望代码的顺序明确地决定程序的行为。

于 2013-02-28T16:16:56.227 回答
1

是的,正如每个人都提到的那样,您有比赛条件。

在您的情况下,它暴露了大多数人起初不期望的闭包行为:闭包捕获变量,而不是它的值。这个问题可以很容易地在单线程案例中显示:

string text = "t1";
Action a1 =  () => Console.WriteLine (text);
a1(); // prints "t1"
text = "t2";
Action a2  = () => Console.WriteLine (text) ;

a1(); // prints "t2" 
a2(); 
于 2013-02-28T16:39:23.873 回答
1

是的,这是一个简单的多线程问题。

当第一个线程甚至没有启动时,您更改文本变量的值。然后第一个线程以新值开始,你有一个双 't2'

于 2013-02-28T16:15:48.287 回答
1

“有时它会产生双倍的 t2”

text 的值在第一个之前已更改为“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();
于 2013-02-28T16:18:01.647 回答
-1

因此,最简单的方法是对变量使用锁

这可以防止一个线程在另一个线程使用该变量时访问该变量

于 2013-02-28T16:18:23.677 回答