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

9
请解释下面代码的输出:
如果我调用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个回答

8
Thread.start()方法会启动一个新的线程,这个线程的入口点是run()方法。如果你直接调用run()方法,它将在同一个线程中执行。由于调用Thread.start()会启动一个新的执行线程,run()方法可能会在主方法的其余部分执行后(如你的示例中)被调用。
将你的主方法更改为调用th1.start()并重复运行,你会看到有时会输出:
EXTENDS RUN>>
RUNNABLE RUN >>

有时它会输出:

RUNNABLE RUN >>
EXTENDS RUN>>

根据Java选择如何调度您的两个线程而定。请查看此Java教程

我一直在尝试弄清楚为什么我的Android多线程没有起作用。结果发现我总是调用run()而不是start() - Peterdk

2
当你调用th1.run()时,你正在运行当前线程中的run方法,因此必须在调用th2.run()之前发生。
当你调用th1.start()时,run方法将在一个新线程上被调用。在这种情况下,它是在调用th2.run()之后发生的。(实际上,理论上它可能会在th2.run()之前发生,但是当前和先前的Sun实现thread.start()不会立即使当前线程“让出”给新线程。)
这说明了使用Java线程的常见错误。如果你想在新线程上运行东西,必须调用thread.start()。直接调用thread.run()几乎总是错误的。

0
当你调用`.run()`方法时,该方法被调用并执行其中的代码,就像调用任何其他方法一样。但是,如果你在一个线程上调用`.start()`方法,`run()`方法将在该线程中运行,而不是按顺序在主线程中运行。
因此,当你调用`th1.start()`方法时,你同时在两个线程中执行代码:主线程将继续创建th2,然后调用其`run`方法,而th1线程将调用自己的`run`方法。由于它们是并行执行的,所以它们的顺序不能保证。

0

执行run()是同步的 - 执行start()是异步的。

run()的调用只是普通的同步方法调用,按照顺序执行。使用th1.start(),将启动一个新线程 - 现在是一场双人赛跑 - 两个run()方法现在独立执行 - 先完成的胜出,没有任何保证。

但如果顺序不能保证,为什么新线程的输出大多数情况下都较晚呢?实际上,启动新线程需要一些时间,因此当它得到启动时,另一个run()方法已经执行完毕。即使在多核计算机上,两个线程都可以同时执行,新线程通常也会排在最后,因为线程启动涉及更多工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接