Java 什么';Thread start()和Runnable run()之间的区别是什么
假设我们有两个Runnable:Java 什么';Thread start()和Runnable run()之间的区别是什么,java,multithreading,concurrency,runnable,Java,Multithreading,Concurrency,Runnable,假设我们有两个Runnable: 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(
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();
}
第一个示例:没有多线程。两者都在单个(现有)线程中执行。没有线程创建
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
是类的对象。当您调用t1.start()
时,它会启动一个新线程,并在内部调用r1
的run()
方法在该新线程中执行。如果您直接调用run()
,它将在调用线程上执行,就像任何其他方法调用一样Thread.start()
是实际创建新线程所必需的,以便并行执行runnable的run
方法。在第一种情况下,您只是调用r1
和r2
对象的run()
方法
在第二种情况下,您实际上创建了两个新线程
start()
将在某个时候调用run()
Thread.start()
code向调度程序注册线程,调度程序调用run()
方法。另外,Thread
是类,而Runnable
是接口。实际上Thread.start()
创建一个新线程并有自己的执行场景
Thread.start()
异步调用run()
方法,将新线程的状态更改为Runnable
但是Thread.run()
不会创建任何新线程。相反,它在当前正在运行的线程中同步执行run方法
如果您使用的是Thread.run()
,那么您根本没有使用多线程的功能 如果在main方法中执行run()
,main方法的线程将调用run
方法,而不是您需要运行的线程
start()
方法创建新线程,必须对其执行run()
方法区别在于thread.start()
启动调用run()
方法的线程,而Runnable.run()
只调用当前线程上的run()
方法。调用run()
与任何其他方法调用一样,在调用线程上执行。而Thread.start()
会创建一个新线程。
调用
run()
是一个编程错误 各位成员提出的观点都是正确的,所以我只想补充一点。问题是JAVA不支持多重继承。但是,如果您想从另一个类a派生一个类B,但您只能从一个类派生,该怎么办呢。现在的问题是如何“派生”两个类:A和Thread。因此,您可以使用Runnable接口
public class ThreadTest{
public void method(){
Thread myThread = new Thread(new B());
myThread.start;
}
}
public class B extends A implements Runnable{...
Thread类中单独的start()和run()方法提供了两种创建线程程序的方法。start()方法启动新线程的执行并调用run()方法。start()方法立即返回,新线程通常会继续,直到run()方法返回为止
线程类的run()方法不执行任何操作,因此子类应该使用代码重写该方法,以便在第二个线程中执行。如果使用Runnable参数实例化线程,则线程的run()方法将在新线程中执行Runnable对象的run()方法
根据线程程序的性质,直接调用Thread run()方法可以获得与通过start()方法调用相同的输出,但在后一种情况下,代码实际上是在新线程中执行的。t.start()
是库为您的代码提供的在需要新线程时调用的方法
r.run()
是为库提供的在新线程中调用的方法
这些答案中的大多数都忽略了全局,这就是,就Java语言而言,
t.start()
和r.run()
之间的区别并不比其他两种方法之间的区别大
它们都只是方法。它们都在调用它们的线程中运行。他们都做他们被编码要做的事情,然后他们都返回,仍然在同一个线程中,给他们的调用者
最大的区别是,t.start()
的大部分代码是本机代码,而在大多数情况下,r.run()
的代码将是纯Java代码。但这没什么区别。代码就是代码。本机代码更难找到,当您找到它时也更难理解,但它仍然只是告诉计算机该做什么的代码
那么,t.start()
做什么呢
它创建一个新的本机线程,安排该线程调用t.run()
,然后告诉操作系统让新线程运行。然后它回来了
那么r.run()
做什么呢
有趣的是,问这个问题的人就是写这个问题的人
r.run()
执行您(即编写它的开发人员)设计的任何操作。不同之处在于,当程序调用start()
方法时,将创建一个新线程,并在新线程中执行run()
中的代码:而如果您直接调用run()
方法,不会创建新线程,并且run()
中的代码将直接在当前线程中执行
Java线程中的start()
和run()
之间的另一个区别是不能调用start()
两次。一旦启动,第二个start()
调用将抛出 /**
* Causes this thread to begin execution; the Java Virtual Machine
* calls the <code>run</code> method of this thread.
* <p>
* The result is that two threads are running concurrently: the
* current thread (which returns from the call to the
* <code>start</code> method) and the other thread (which executes its
* <code>run</code> method).
* <p>
* It is never legal to start a thread more than once.
* In particular, a thread may not be restarted once it has completed
* execution.
*
* @exception IllegalThreadStateException if the thread was already
* started.
* @see #run()
* @see #stop()
*/
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
start0();
if (stopBeforeStart) {
stop0(throwableFromStop);
}
}
private native void start0();
public class Main1
{
A a=new A();
B b=new B();
a.run();//This call run() of Thread because run() of Thread only call when class
//implements with Runnable not when class extends Thread.
b.run();//This not run anything because no run method found in class B but it
//didn't show any error.
a.start();//this call run() of Thread
b.start();//this call run() of Thread
}
class A implements Runnable{
@Override
public void run() {
System.out.println("A ");
}
}
class B extends Thread {
@Override
public void run() {
System.out.println("B ");
}
}