对于具有multiThread ConsoleWriteLine的循环

时间:2015-12-05 15:30:08

标签: c# multithreading thread-safety

我的代码如下:

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

输出

3
3
3
3
5
6
8
8
10
10

在我看来,经过10次迭代后,i的最大值应为9。 我知道multiThread结果输出不正确,但最大值是如何表现的呢?

3 个答案:

答案 0 :(得分:2)

for循环中,i的最大值为9.当i不再小于10时,循环结束,因此在循环i之后是10.

你的一些线程是在循环结束之前启动的,这就是你从3到8得到结果的原因。循环结束后启动了两个线程,所以你得到了10个。

答案 1 :(得分:1)

在启动线程后,您应该注意意外修改捕获的变量,如i,因为i是共享的。因此,将i复制到本地变量,如下所示:

for (int i = 0; i < 10; i++)
{
     var i1 = i;
     new Thread(() => Console.WriteLine(i1)).Start();
}

在此处详细了解闭包:The Beauty of ClosuresLambda expressions and captured variables.

答案 2 :(得分:1)

它被称为捕获的变量,它正是问题Joseph Albahari谈论Here

以下是他的总结:

  

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

     

解决方案是使用临时变量,如下所示:

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

变量temp现在是每个循环迭代的本地变量。因此,每个   线程捕获不同的内存位置,没有问题。