【发布时间】:2017-03-14 15:54:32
【问题描述】:
我有一个简单的代码,它有一个锁并创建了 5 个线程。
static readonly object _object = new object();
static void A(int currentValue)
{
lock (_object)
{
Console.WriteLine(currentValue + " Start");
Console.WriteLine(currentValue + " End");
}
}
static void Main(string[] args)
{
for (int i = 0; i < 5; i++)
{
Thread t = new Thread(() => A(i));
t.Name = "Thread " + i;
Console.WriteLine(t.Name + " Created");
t.Start();
}
Console.ReadKey();
}
当我运行此代码时,输出中会显示以下内容。
Thread 0 Created
Thread 1 Created
1 Start
1 End
Thread 2 Created
2 Start
2 End
Thread 3 Created
3 Start
3 End
Thread 4 Created
4 Start
4 End
5 Start
5 End
当我只创建 5 个线程 (0 - 4) 时。为什么我会看到 5 Start 和 5 End 的条目?
【问题讨论】:
-
尝试前增量而不是后增量,例如++i
-
我不确定根本原因,但我想这些是相关的:我注意到您没有“0 Start”和“0 End”行。看起来 i 在每个线程运行之前都在增加,但对于“线程创建”行仍然是相同的 i。我最好的猜测是,当线程运行时,它采用 i 的最新值,而不是声明线程变量时 i 的值。您是否始终获得相同的结果? (另请参阅 Peter Duniho 的回答 - 非常相关)
-
问题是在线程启动的时候变量
i已经改变了。你很幸运,任何线程甚至在整个循环完成之前就开始了。通常,当您编写这样的错误时,行为是 所有 线程打印5。有关修复它的详细信息,请参阅标记重复(Lasse 的答案)。 -
更重要的是,无论代码中是否存在
lock语句,所描述的行为都将保持不变,所以问题是 - 为什么 存在lock语句? -
@MongZhu 我怀疑在现实世界中
A会在最终锁定之前做一些可并行化的工作,以便写入Console,或者将输出添加到集合中,或者做一些其他不-线程安全。
标签: c# multithreading