我的代码如下:
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结果输出不正确,但最大值是如何表现的呢?
答案 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 Closures
和Lambda 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现在是每个循环迭代的本地变量。因此,每个 线程捕获不同的内存位置,没有问题。