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

c# Lock Doesn`t work / Critical Section

我正在尝试在 FOR 循环中使用两个不同的线程来推进静态 (int) 计数器,因此如果循环是 运行s 10 倍我 (should) 得到计数器=20。出于某种原因,我每次 运行 循环 (19,20,21) 时都会得到不同的值,即使我使用 LOCK 访问该计数器,(控制台中的代码 运行s):

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++;
            }
        }

你遇到了三个问题:

  • 你实际上 运行 循环 11 次:

    for (int i = 0; i <= ForLength; i++) // i=0 to i=10 *inclusive*
    
  • 您没有加入线程(或休眠),因此在您编写输出时其中一些线程可能尚未完成

  • 当您在主线程中读取 Counter 时,您没有在 syncObject 上进行同步,因此您可能无法观察到最近写入的值

如果您不想使用 Thread.Join,只需添加对 Thread.Sleep 的调用,例如Thread.Sleep(5000) - 极有可能 所有线程在那之后都会完成。然后你可以使用:

lock (syncObject)
{
    Console.WriteLine(Counter);
}

简而言之,lock 没有任何问题,尽管您最好使用 Interlocked.Increment