繁体   English   中英

Thread.Sleep() 如何工作?

[英]How Thread.Sleep() works?

所以我试图研究如何使用多线程,但我注意到了一些我不太明白的东西。

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

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(首先执行的)是最后一个完成的呢?

锁定声明

现在,如果我们添加一个 lock 语句,像这样:

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() 结束之前就开始运行了! 这里发生了什么? 其背后的过程和逻辑是什么?

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM