请解释Thread run()和start()方法的输出

时间:2010-06-12 04:32:14

标签: java multithreading

请解释以下代码的输出:

如果我拨打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();
    }
}

4 个答案:

答案 0 :(得分:8)

Thread.start()方法启动一个新线程,该线程的入口点是run()方法。如果直接调用run(),它将在同一个线程中执行。鉴于调用Thread.start()将启动一个新的执行线程,run()方法可能会在(如在您的示例中)之后调用主方法的其余部分执行。

更改主要方法以致电th1.start()并重复运行,您会看到有时会输出:

EXTENDS RUN>>
RUNNABLE RUN >>

有时输出:

RUNNABLE RUN >>
EXTENDS RUN>>

取决于java选择如何安排2个线程。

查看java tutorial

答案 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()方法已经运行了。即使在两个线程可以同时执行的多核机器上,新线程通常也会持续,因为线程启动涉及更多工作。