[英]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.