对于以下程序,在eclipse上运行和调试时会出现不同的输出。
public class MyClass implements Runnable {
public static void main (String[] args) throws Exception {
Thread t = new Thread(new MyClass());
t.start();
System.out.print("Started");
t.join();
System.out.print("Complete");
}
public void run() {
for (int i = 0; i < 4; i++) {
System.out.print(i);
}
}
}
当作为java应用程序运行时, OUTPUT 是
Started0123Complete
签入 调试 模式 OUTPUT 时
0123StartedComplete
有人可以为此提供帮助吗?是因为两个线程? main thread
以及以t.start()
开头的线程。如果是,那么为什么主线程执行优先于先完成?
由于
答案 0 :(得分:6)
字符串&#34;开始&#34;的顺序根据定义,打印出的整数是不确定的。致电start
后,无法保证run
方法中的代码将在调用join
之前出现的任何其他语句之前或之后执行。这是多线程应用程序的本质。
您在调试模式与运行模式下看到某个输出的事实可能完全是偶然的,如果您多次运行代码或在JVM的不同平台/版本上运行您的代码,则可能会发生更改。如果在这种情况下需要确定性顺序,那么实现它的唯一方法是在调用start
之前打印字符串或引入其他类型的信号量以强制线程等待主线程或反之亦然。
答案 1 :(得分:2)
这是巧合。您无法控制线程调度程序。
但是,在调试环境中,debugger会插入代码以检查值和执行。此检查增加了每个线程时间片完成的工作量。
例如,在常规运行中,主线程可能只需要1个时间片来创建新线程对象,启动它并打印Started
消息。然后将发生上下文切换,第二个线程将进行更改工作。在调试运行中,主线程只有足够的时间来创建新的线程对象并启动相应的线程。然后会发生上下文切换,另一个线程会做它的事情。
答案 2 :(得分:1)
与处于调试模式无关。 无法保证何时执行此操作
System.out.print("Started"); //this is in the main thread
与
相比for (int i = 0; i < 4; i++) { // this is in the started thread
System.out.print(i);
}
甚至可以
01Started23Complete
答案 3 :(得分:0)
是的,它因为2个线程而输出是不可预测的。 不,主线程没有获得高优先级,因为它是MAIN。 你不能说多线程中任何特定的交错执行。
在Debug中,我的猜测是你为主线程设置了一个断点,所以它等待,同时另一个线程可能已经执行了。
答案 4 :(得分:-1)
在两者(运行/调试)中,模式输出将为
<强> Started0123Complete 强>
您看到结果 0123StartedComplete ,因为您必须在主线程代码中包含调试点,这就是原因。
如果你想更好地理解,那么将run()方法移到MyClass中并将调试器点放在run方法中,现在你会看到它打印为 Started0123Complete 。
在内部,主线程正在创建子线程“t”,并且当调用t.start()时,它正在等待捕获监视器以执行线程(即run()),并且当您在主线程中添加调试语句时,子线程进入监视器并且运行方法正在执行,一旦完成,主线程再次启动。