【问题标题】:Counting threads with lock and without (c#)计算带锁和不带锁的线程(c#)
【发布时间】:2013-03-09 15:27:57
【问题描述】:

Grant Crofton's answer对问题“无序线程问题”有评论:

“如果你移除锁,最终计数可能会少于 100。”

为什么?

这是上下文的代码

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

【问题讨论】:

    标签: c# .net multithreading asynchronous synchronization


    【解决方案1】:

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

    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
    

    这些被称为Race Conditions 并通过使操作Atomic 解决

    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
    

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 奇怪的结果也暗示超过100个?!
      • 不,因为启动线程的循环不会超过一百。
      猜你喜欢
      • 1970-01-01
      • 2019-04-04
      • 1970-01-01
      • 1970-01-01
      • 2015-08-25
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 2020-12-07
      相关资源
      最近更新 更多