2

我在网上看到一段代码,指出调用这样的线程会导致不确定的输出“0223557799”或类似的东西。(你明白了)

for (int i = 0; i < 10; i++)
   new Thread (() => Console.Write (i)).Start();

这是给出的原因:

“问题是 i 变量在循环的整个生命周期中都指向相同的内存位置。因此,每个线程都会调用 Console.Write 变量,其值可能会在运行时发生变化!”

但是,按照惯例,当参数按值传递时——每个新的 Thread 调用都应该发送的增量顺序,对吗?只有当值通过引用传递时,上述原因才成立。那么,在 C# 多线程中,值是否通过引用传递?

我是 C# 新手,请理解这个问题是否幼稚。

4

2 回答 2

10

您的程序等效于以下程序:

class Locals
{
    public int i;
    public void M() { Console.Write(this.i);
}

...
Locals locals = new Locals();
for (locals.i = 0; locals.i < 10; locals.i++)
  new Thread (locals.M).Start();

现在很清楚为什么你会得到你所做的结果吗?不是i按值传递的;而是通过引用locals传递给每个线程。每个线程都在共享,因此可以看到 的当前值,而不是创建线程时的值。 locals.ilocals.ii

于 2013-07-21T17:42:58.013 回答
8

这里的问题不止一个。它肯定始于 for() 循环变量捕获问题,如本文所述。这往往会产生“10”作为输出,但不能保证会发生这种情况,因为线程可能在循环仍在迭代时执行。

但是该程序也存在核心线程问题,无法保证线程会按预期顺序调用 Console.Write()。这只是可能的,但一个线程可能会领先于另一个线程并获得保护控制台的锁。一个称为“线程竞赛”的问题。

于 2013-07-21T16:28:49.480 回答