假设我们有两个Runnables:
class R1 implements Runnable {
public void run() { … }
…
}
class R2 implements Runnable {
public void run() { … }
…
}
那么这两者的区别是什么呢:
public static void main() {
R1 r1 = new R1();
R2 r2 = new R2();
r1.run();
r2.run();
}
这:
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();
}
T.start()是标准库为您的代码提供的方法,当您需要一个新线程时可以调用它。
R.run()是为库在新线程中调用提供的方法。
这些答案大多数都忽略了一个大问题,即就Java语言而言,t.t start()和r.r run()之间的差异并不比其他任何两个方法之间的差异大。
它们都是方法。它们都运行在调用它们的线程中。它们都做它们被编码要做的事情,然后它们都返回给它们的调用者,仍然在同一个线程中。
最大的区别是t.t start()的大部分代码是本地代码,而在大多数情况下,r.r run()的代码将是纯Java。但这并没有太大的区别。代码就是代码。原生代码更难找到,找到后也更难理解,但它仍然只是告诉计算机该做什么的代码。
那么,t.start()做什么呢?
它创建了一个新的本机线程,它安排该线程调用t.run(),然后它告诉操作系统让新线程运行。然后它又回来了。
r.run()做什么?
有趣的是,问这个问题的人正是写这个问题的人。r.r run()执行您(即编写它的开发人员)设计它要执行的任何操作。
第一个例子:没有多线程。两者都在单个(现有)线程中执行。没有线程创建。
R1 r1 = new R1();
R2 r2 = new R2();
r1和r2只是实现Runnable接口并因此实现run()方法的类的两个不同对象。当你调用r1.run()时,你是在当前线程中执行它。
第二个例子:两个独立的线程。
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1和t2是Thread类的对象。当调用t1.start()时,它会启动一个新线程,并在内部调用r1的run()方法以在该新线程中执行它。