1

Grant Crofton's answer to the question "Unordered threads problem" has a comment:

"And if you remove the lock the final count might be less than 100."

Why?

Here is the code for context

class Program
{
    static object locker = new object();
    static int count=0;

    static void Main(string[] args)
    {
        for (int j = 0; j < 100; j++)
        {
            (new Thread(new ParameterizedThreadStart(dostuff))).Start(j);
        }
        Console.ReadKey();
    }

    static void dostuff(object Id)
    {
        lock (locker)
        {
            count++;
            Console.WriteLine("Thread {0}: Count is {1}", Id, count);
        }
    }
}
4

2 回答 2

4

这是没有可能发生的情况:

Count = 0

ThreadA Reads Count As 0 
ThreadB Reads Count As 0
ThreadA Writes New Incremented Count As 0 + 1
ThreadB Writes New Incremented Count As 0 + 1

Count = 1

这些被称为竞争条件,并通过使操作原子化来解决

Count = 0

ThreadB Wins Race To Lock()
ThreadB Reads Count As 0
ThreadB Writes New Incremented Count As 0 + 1
ThreadB Unlocks

ThreadA Next for Lock()
ThreadA Reads Count As 1
ThreadA Writes New Incremented Count As 1 + 1
ThreadA Unlocks

Count = 2
于 2013-03-09T15:42:57.583 回答
2

因为锁保护count变量免受多个线程试图一次增加它的影响。如果发生这种情况,可能会给您带来奇怪的结果。

锁确保线程一次只能进入一个函数,因此一次只能执行一个函数内部的操作。

如果你删除它,那么线程可以同时进入,在任何这些操作的中间被中断,给你奇怪的结果,乱序的结果等等。

于 2013-03-09T15:32:56.197 回答