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

Ran*_*Ran -3 .net c# multithreading locking critical-section

我试图在FOR循环中使用两个不同的线程来推进静态(int)计数器,所以如果循环运行10次,我(应该)得到计数器= 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++;
            }
        }
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 8

你有三个问题:

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

    for (int i = 0; i <= ForLength; i++) // i=0 to i=10 *inclusive*
    
    Run Code Online (Sandbox Code Playgroud)
  • 你没有加入你的线程(或睡眠),因此在你编写输出时它们中的一些可能还没有完成

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

如果您不想使用Thread.Join,只需添加一个调用Thread.Sleep,例如Thread.Sleep(5000)- 之后可能所有线程都已完成.然后你可以使用:

lock (syncObject)
{
    Console.WriteLine(Counter);
}
Run Code Online (Sandbox Code Playgroud)

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