线程赛,为什么线程如此工作?

5 c# static multithreading thread-safety

交换两行代码有两个不同的结果(使用Console.Write()完成= true)

如果我把done = true,首先,结果将是: True

否则如果我首先放置Console.WriteLine(),结果将是: False False

为什么?(仔细看,bool变量是静态的!)

using System;
using System.Threading;

class Program
{
    static bool done;

    static void Main(string[] args)
    {
        new Thread(test).Start();
        test();
    }

    static void test()
    {
        if (!done)
        {
            done = true;
            Console.WriteLine(done);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

mus*_*fan 8

我敢打赌,在Console.WriteLine第二次调用test()有机会执行时,将足以保持线程忙碌.

所以基本上调用WriteLine延迟设置的done时间足以让第二次调用test能够测试done并找到它仍然设置为false.

如果你把它保留在显示done = true;之前,那么在写入控制台之前,这将几乎立即设置,因此第二次测试将找到done设置,true因此不会执行Console.WriteLine.

希望一切都有道理.


我刚发现它包含的代码非常类似于你的问题.如果你没有从这个页面得到你的问题,那么我建议阅读,因为它更详细地解释了这种效果的原因.

使用以下密钥提取:

在单处理器计算机上,线程调度程序执行时间分片 - 在每个活动线程之间快速切换执行.在Windows下,时间片通常在几十毫秒的区域内 - 远大于实际切换一个线程与另一个线程(通常在几微秒区域内)之间的上下文中的CPU开销.

所以基本上调用就Console.WriteLine需要花费足够长的时间让处理器决定在你的额外线程被允许继续之前让主线程再次运行(并最终设置done标志)

  • +1,还要注意OP中强调的`static`关键字并不意味着它的所有线程都是安全的. (3认同)
  • 它非常有意义 - Console.WriteLine调用是应用程序中唯一的实质性操作,需要在输出缓冲区上进行锁定. (2认同)