不一致的线程

本文关键字:线程 不一致 | 更新日期: 2023-09-27 18:01:47

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

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,因为它是在最后一个变量赋值之后开始的。我说的对吗?

不一致的线程

你说得对;参见Wikipedia上的竞态条件。

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

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

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

'有时会产生双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();

大家都说你有竞态。

在你的例子中,它暴露了闭包的行为,大多数人一开始都没有预料到:闭包捕获变量,而不是它的值。这个问题可以很容易地在单线程情况下显示:

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

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

使用锁。

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