Thread start()和Runnable run()之间的区别是什么

Ori*_*ski 209 java concurrency multithreading runnable

假设我们有这两个Runnables:

class R1 implements Runnable {
    public void run() { … }
    …
}

class R2 implements Runnable {
    public void run() { … }
    …
}
Run Code Online (Sandbox Code Playgroud)

那么这有什么区别:

public static void main() {
    R1 r1 = new R1();
    R2 r2 = new R2();

    r1.run();
    r2.run();
}
Run Code Online (Sandbox Code Playgroud)

还有这个:

public static void main() {
    R1 r1 = new R1();
    R2 r2 = new R2();
    Thread t1 = new Thread(r1);
    Thread t2 = new Thread(r2);

    t1.start();
    t2.start();
}
Run Code Online (Sandbox Code Playgroud)

Bhe*_*ung 293

第一个例子:没有多线程.两者都在单个(现有)线程中执行.没有线程创建.

R1 r1 = new R1();
R2 r2 = new R2();
Run Code Online (Sandbox Code Playgroud)

r1并且r2只是实现Runnable接口的类的两个不同对象,从而实现该run()方法.当你打电话时,r1.run()你正在当前的线程中执行它.

第二个例子:两个独立的线程.

Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
Run Code Online (Sandbox Code Playgroud)

t1并且t2是该类的对象Thread.当你调用时t1.start(),它会启动一个新线程并调用内部run()方法r1在该新线程中执行它.

  • Couuld我认为在我们调用Thread#start()之前,没有真正相对于os线程发生的事情?它只是一个java对象. (4认同)
  • 根据文档,这是正确的.检查线程对象初始化代码,该代码符合文档.同样在源代码中,它是`start()`,它调用一个natvie方法,它必须使os线程相关的事情发生. (3认同)
  • 线程构造函数文档是[这里](https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#Thread(java.lang.ThreadGroup,%20java.lang.Runnable,% 20java.lang.String)).线程对象初始化源是[这里](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Thread.java#Thread.init%28java .lang.ThreadGroup%2Cjava.lang.Runnable%2Cjava.lang.String%2Clong%29).`start()`方法源是[here](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Thread.java#Thread.启动%28%29). (2认同)

Mik*_*els 89

如果你只是run()直接调用,它就会在调用线程上执行,就像任何其他方法调用一样.Thread.start()需要实际创建一个新线程,以便run并行执行runnable的方法.

  • 在Hotspot JVM中,java线程和本机线程之间存在直接映射.`Thread.start()`调用使线程状态从*new*state移动到*Runnable*state.Runnable并不意味着线程正在运行.本机线程初始化后,本机线程调用Java线程中的`run()`方法,这使得线程状态从*Runnable*更改为*Running*.当线程终止时,释放本机和Java线程的所有资源. (2认同)
  • @twlkyao在Javadoc中用于`Thread`。 (2认同)

use*_*421 67

区别在于Thread.start()启动一个调用该run()方法的线程,而Runnable.run()只是run()在当前线程上调用该方法.


Jai*_*tel 31

区别是,当程序调用start()方法,一个新的被创建的线程和代码内run()被执行的线程,而如果调用run()方法是直接没有新的线程将被创建,里面的代码run()将在当前线程直接执行.

Java线程和Java线程之间的另一个区别是你不能再调用两次.一旦启动,第二次调用将抛出Java,而您可以多次调用方法,因为它只是一个普通的方法.start()run()start()start()IllegalStateExceptionrun()


adi*_*tya 22

实际上Thread.start()创建一个新线程并拥有自己的执行场景.

Thread.start()run()异步调用该方法,将新Thread的状态更改为Runnable.

但是Thread.run()不会创建任何新线程.相反,它同步执行当前运行线程中的run方法.

如果您正在使用,Thread.run()那么您根本就没有使用多线程的功能.


Nar*_*ggi 8

invoke run()正在调用线程上执行,就像任何其他方法调用一样.而 Thread.start()创建一个新的线程.调用run()是一个程序化的bug.


小智 6

如果run()在main方法中执行,main方法的线程将调用run方法而不是运行所需的线程.

start()方法创建新线程,并且必须为其执行该run()方法

  • @EJP,作者`main`,作者指的是调用方法.他的回答非常好.+1 ;-) (3认同)

CHA*_*HAS 5

Thread.start()代码使用调度程序注册Thread,调度程序调用该run()方法.此外,Thread是类同时Runnable是一个接口.


Sol*_*low 5

t.start() 是库提供的方法,供您在需要新线程时调用的代码。

r.run()提供给新线程中调用的方法。


这些答案中的大多数都忽略了大局,即就 Java 语言而言,t.start()r.run()任何其他两种方法之间没有更多区别。

它们都只是方法。它们都在调用它们的线程中运行。他们都做他们被编码要做的事情,然后他们都返回,仍然在同一个线程中,返回给他们的调用者。

最大的区别是大部分代码t.start()本机代码,而在大多数情况下,代码r.run()将是纯 Java 的。但这并没有太大区别。代码就是代码。本机代码更难找到,当你找到它时也更难理解,但它仍然只是告诉计算机要做什么的代码。

那么,有什么作用t.start()呢?

它创建一个新的本地线程,安排该线程调用t.run(),然后告诉操作系统让新线程运行。然后它返回。

有什么作用r.run()

有趣的是,问这个问题的人就是这个问题的人。 r.run()(即编写它的开发人员)设计它做的任何事情。