请解释以下代码的输出:
如果我拨打th1.run()
,则输出为:
EXTENDS RUN>>
RUNNABLE RUN>>
如果我拨打th1.start()
,则输出为:
RUNNABLE RUN>>
EXTENDS RUN>>
为何这种不一致?请解释一下。
class ThreadExample extends Thread{
public void run() {
System.out.println("EXTENDS RUN>>");
}
}
class ThreadExampleRunnable implements Runnable {
public void run() {
System.out.println("RUNNABLE RUN>>");
}
}
class ThreadExampleMain{
public static void main(String[] args) {
ThreadExample th1 = new ThreadExample();
//th1.start();
th1.run();
ThreadExampleRunnable th2 = new ThreadExampleRunnable();
th2.run();
}
}
答案 0 :(得分:8)
Thread.start()
方法启动一个新线程,该线程的入口点是run()
方法。如果直接调用run(),它将在同一个线程中执行。鉴于调用Thread.start()
将启动一个新的执行线程,run()
方法可能会在(如在您的示例中)之后调用主方法的其余部分执行。
更改主要方法以致电th1.start()
并重复运行,您会看到有时会输出:
EXTENDS RUN>>
RUNNABLE RUN >>
有时输出:
RUNNABLE RUN >>
EXTENDS RUN>>
取决于java选择如何安排2个线程。
答案 1 :(得分:3)
当您致电th1.run()
时,您正在当前线程中运行run
方法,因此必须在调用th2.run()
之前进行。
当您致电th1.start()
时,您正在新线程上调用run
方法。在这种情况下,它发生在调用th2.run()
之后。 (事实上,理论上它可能发生在th2.run()
之前......但thread.start()
的当前和以前的Sun实现不会导致当前线程立即“屈服”到新线程。 )
这说明了使用Java线程时常见的错误。如果要在新线程上运行内容,则必须调用thread.start()
。直接调用thread.run()
几乎总是一个错误。
答案 2 :(得分:0)
当您调用.run()
时,将调用该方法,并且执行的代码与任何其他方法相同。但是,如果在线程上调用.start()
,run()
方法将在该线程中运行,而不是在主线程中顺序运行。
因此,当您调用th1.start()
时,您的代码会同时在两个线程中执行:主线程将继续创建th2然后调用其run
方法,而th1线程将调用它拥有run
方法。这些订单无法保证,因为它们并行执行。
答案 3 :(得分:0)
执行run()
是同步的 - 执行start()
是异步的。
对run()
的调用只是一个常规的同步方法调用,它们按此顺序发生。使用th1.start()
,一个新的线程启动 - 它现在是两匹马 - 两个运行方法现在独立执行 - 第一个到完成胜利,并且不保证订单。
但如果订单无法保证,为什么新的Thread会在大部分时间后打印?实际上,启动一个新线程需要一些时间,所以当它开始时,另一个run()
方法已经运行了。即使在两个线程可以同时执行的多核机器上,新线程通常也会持续,因为线程启动涉及更多工作。