c#锁不起作用/关键部分

时间:2015-03-23 18:39:34

标签: c# .net multithreading locking critical-section

我试图在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++;
            }
        }

1 个答案:

答案 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