从下面的代码中,我会在x之前打印出“y”,但“x”会先开始打印。我是以线性方式阅读这个,所以为什么“x”首先开始打印,即使在主要方法中首先调用t.Start()?
static void Main()
{
Thread t = new Thread(ThreadTest.WriteY);
t.Start();
for(int i = 0; i < 1000; i++) Console.Write("x");
}
public class ThreadTest
{
public static void WriteY()
{
for(int i = 0; i < 1000; i++) Console.WriteLine("y");
}
}
答案 0 :(得分:11)
嗯,请考虑这种方式。
给你的朋友一堆文件,并自己保管。
然后你告诉你的朋友“开始在那些文件上写出数字”,然后立即开始做同样的事情。
现在告诉我,你们谁先完成?
而且,考虑到这是你的问题,为什么?
在这里确定性地输入正确答案是不可能的,因为有太多事情会影响你们两个人的速度:
所以基本上,你的朋友可能会在你设法开始之前开始,反之亦然,但事先你不知道,这不是“正确答案”。
每次运行此程序时,它都有可能表现不同,至少就两个线程之间的执行顺序而言。
话虽如此,启动一个新线程会产生开销,这可能会使得规模有利于主线程在额外线程之前进入循环。但是,如果不可能发生相反的情况,我会感到惊讶。
答案 1 :(得分:3)
当您生成新线程时,操作系统会接管并安排稍后进行的工作。关键是你无法知道它何时会发生,这就是为什么你多次运行同一个应用程序并且每次都看到不同的结果。
答案 2 :(得分:3)
启动新线程可能需要相当长的时间,因此在WriteY
运行之前需要一段时间。与此同时,主线程将继续运行,因此您将看到大多数({1}} s打印在大多数情况下(如果不是全部的话)。
此外,调度本身由OS处理。
简而言之:您不应该尝试根据阅读源代码来猜测执行顺序。
答案 3 :(得分:2)
仅仅因为你在某个时间启动一个线程并不意味着该线程中的代码将在执行调用方法中的下一行代码之前启动。
我猜你可以运行这个程序数千次,其中一些以'y'开头,另一些以'x'开头。
答案 4 :(得分:1)
因为不确定首先开始的是什么。没有执行线程的确定性顺序。如果您启动程序n次,可以假设您首先看到x和y打印。
如果您想确保执行线程的顺序,您应该查看Thread.Join
答案 5 :(得分:1)
线程执行顺序是不可预测的
在这种情况下,它可能是构建线程(stackframe / etc)的代码,这会降低速度