Thread.Sleep()如何工作?

时间:2019-02-02 22:46:59

标签: c# multithreading thread-sleep

所以我试图研究如何使用多线程,但我发现有些东西我还不太了解。

在下一段代码中,尽管foo与线程相同,但doo()似乎在线程完成之前开始运行。

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

public static void foo()
{

    Console.WriteLine("1");
    Thread.Sleep(3000);
    Console.WriteLine("2");
}

public static void doo()
{
    Console.WriteLine("do");
}

输出为:

  

1个//螺纹

     

1 // foo

     

2 // foo

     

别//斗

     

2 //螺纹

假设doo()在没有foo()的情况下无法开始运行,我们假定最后的“ 2”输出来自第一个线程。

怎么可能?尽管foo()和Thread由于具有相同的功能而具有相同的睡眠时间,但为什么Thread(首先执行)是最后一个要完成的睡眠?

锁定声明

现在,如果我们增加一个锁的语句,像这样的:

static object syncLock = new object();

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

public static void foo()
{
    lock (syncLock)
    {
        Console.WriteLine("1");
        Thread.Sleep(3000);
        Console.WriteLine("2");
    }        
}

public static void doo()
{
    Console.WriteLine("do");
}

输出为:

  

1个//螺纹

     

2 //螺纹

     

1 // foo

     

别//斗

     

2 //螺纹

现在看来doo()在foo()结束之前开始运行!这是怎么回事流程和背后的逻辑是什么?

2 个答案:

答案 0 :(得分:2)

看,您实际上在主线程和第二个线程(foo())上有两个线程。 在 new Thread(new ThreadStart(foo))。Start(); 之后,执行将从主线程开始,这意味着该线程(主线程)将尝试调用foo(),即您的“ 1 “,之后,主线程进入睡眠状态,第二个线程进入星号foo(),即第二个“ 1”,第二秒进入睡眠状态。现在,主线程将醒来并完成工作“ 2”,“ do”,最后的“ 2”来自sec线程。那是没有锁的。

通过锁定,主线程将执行foo(),而sec将被阻止(“ 1”,3sec,“ 2”),这意味着当foo()解锁时,sec线程可以调用foo(),以及发生这种情况,因为sec打印“ 1”广告进入睡眠状态,并且现在(sec正在睡眠中,CPU寻找可以执行的线程),因此CPU exe执行主线程并打印“ do”,然后sec唤醒并打印“ 2“ ..

答案 1 :(得分:0)

如评论中所述,控制台写入将被缓存。

我只是添加了一个数组,然后在最后打印了它的值。

class Program
    {
        static object syncLock = new object();
        static int[] arr = new int[5];
        static int counter = 0;
        static void Main(string[] args)
        {
            new Thread(new ThreadStart(foo)).Start();
            foo();
            doo();
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine(arr[i]);
            }
        }

        public static void foo()
        {
            arr[counter] = 1;
                counter++;
                Thread.Sleep(3000);
            arr[counter] = 2;
            counter++;
        }

        public static void doo()
        {
            arr[counter] = 3;
            counter++;
        }

    }

输出为:

  

1

     

1

     

2

     

2

     

3

现在更有意义了。谢谢!有关线程,睡眠和锁的任何其他信息将受到赞赏。