我试图在FOR循环中使用两个不同的线程来推进静态(int)计数器,所以如果循环运行10次我(应该)得到counter = 20。由于某些原因,每次运行循环(19,20,21)时我都会得到不同的值,即使我使用LOCK访问该计数器,(代码在控制台中运行):
public static int Counter = 0;
static object syncObject = new object();
static void Main(string[] args)
{
int ForLength = 10;
Thread FirstThread, SecondThread;
for (int i = 0; i <= ForLength; i++)
{
FirstThread = new Thread(RaiseCounter);
FirstThread.IsBackground = false;
SecondThread = new Thread(RaiseCounter);
SecondThread.IsBackground = false;
FirstThread.Start();
SecondThread.Start();
//Console.WriteLine(Counter);
}
Console.WriteLine(Counter);
Console.ReadLine();
}
public static void RaiseCounter ()
{
lock (syncObject)
{
Counter++;
}
}
答案 0 :(得分:8)
你有三个问题:
您实际上正在运行循环 11 次:
for (int i = 0; i <= ForLength; i++) // i=0 to i=10 *inclusive*
你没有加入你的线程(或睡觉),所以在你写输出时它们中的一些可能还没有完成
当您在主线程中阅读syncObject
时,您没有在Counter
上进行同步,因此您可能无法观察到最近写入的值
如果您不想使用Thread.Join
,只需添加对Thread.Sleep
的通话,例如Thread.Sleep(5000)
- 非常可能在此之后所有线程都已完成。然后你可以使用:
lock (syncObject)
{
Console.WriteLine(Counter);
}
简而言之,lock
没有任何问题,尽管您最好使用Interlocked.Increment
。