为什么我们调用线程对象的start()
方法然后调用run()
方法,为什么不直接调用run()
方法?
答案 0 :(得分:65)
[...]为什么我们不直接调用run()方法?
run()
方法只是一种普通方法(由你覆盖)。与任何其他普通方法一样,直接调用它将导致当前线程执行run()
。
所有魔法都发生在start()
内。 start()
方法将导致JVM生成新线程并使新生成的线程执行run()
。
答案 1 :(得分:24)
如果你直接调用run()方法,它的主体在当前线程的上下文中执行。当您调用start()
方法时,将创建一个新线程,并在此新线程中执行run()
方法。
答案 2 :(得分:16)
即使以编程方式我们没有创建任何线程,对于每个应用程序,O.S都会创建一个默认线程来用CPU执行其代码。
直接调用run方法将使该run方法在O.S。
给出的主线程中执行但是创建线程类的目的是确保run方法在不同的线程中执行。除非O.S的线程管理器创建一个线程,否则你的run方法不会在一个单独的线程中执行。要请求O.S创建单独的线程,您必须调用start()方法,该方法将向O.S发送请求以创建线程。一旦O.S创建了一个线程,那么O.S将自动在新创建的线程上下文中调用线程类的run方法。因此,您将提供创建单独线程并在单独线程中执行run方法的目的。
如果你直接调用run方法,那就像O.S不会为你创建任何线程,默认主线程将执行你的run方法。 没有必要为它创建一个单独的线程类!
希望我很清楚。如果您需要更多解释来回答您的问题,请与我们联系。注意:虽然书籍说JVM创建线程,但内部JVM必须向O.S层的线程管理器驱动程序发送请求,以在其线程池中创建新线程。这就是为什么我在这里使用O.S这个术语比JVM更多。
答案 3 :(得分:10)
为什么我们调用线程对象的start()方法来轮流调用 run()方法
不,不。 start()
调用操作系统,该操作系统启动一个新线程,(大大简化)调用run()
方法。同时start()
方法已经返回给它的调用者。它们并不等同。
答案 4 :(得分:9)
Runnable
只是一个界面。实现Runnable
的类没有什么特别之处,只有run
方法。
Thread#start
是一个本机实现的方法,它创建一个单独的线程并调用Thread
的{{1}}方法,在新线程中执行代码。
run
实施Thread
。 Runnable
的代码如下所示:
run
如果@Override
public void run() {
if (target != null) {
target.run();
}
}
实例是通过将Thread
传递给Runnable
的构造函数创建的,则会调用Thread
的{{1}}方法。< / p>
否则,扩展Runnable
的类必须覆盖run
方法才能使Thread
生效。
在run
上调用start
不会创建新主题。
答案 5 :(得分:4)
如果线程已经实例化但未启动,则称其处于新状态。
除非在线程的实例上调用start()方法,否则它不会被称为活动。
如果你没有在新创建的线程实例线程上调用start()方法,不被认为是活着的。
如果没有调用start()方法并且在Thread实例上直接调用run()方法,那么 run()方法中的代码将不会单独运行新线程,但它将开始在现有线程中运行。
查看示例中的问题
class Multi extends Thread{
public void run(){
for(int i=1;i<5;i++){
try{Thread.sleep(500);}catch(InterruptedException e){System.out.println(e);}
System.out.println(i);
}
}
public static void main(String args[]){
Multi t1=new Multi();
Multi t2=new Multi();
t1.run();
t2.run();
}
}
Output:1
2
3
4
5
1
2
3
4
5
正如你在上面的程序中看到的,没有上下文切换,因为这里t1和t2将被视为普通对象而不是线程对象。
答案 6 :(得分:2)
这是由于Java中多线程的设计。
调用start ()
将启动一个新线程,并且调用run()
方法不会启动新线程。
如果在Thread上调用start()
方法,Java虚拟机将调用run()方法,并且两个线程将同时运行 - 当前线程和其他线程或Runnable实现。
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();
在上面的代码中,您看不到run()
方法的调用。
private native void start0()
负责调用run()
方法。 JVM创建与java线程对应的本机线程并调用run()
方法。
有关本机方法的源代码,请参阅此问题:
答案 7 :(得分:1)
我认为你在谈论开始一个线程。如果是这种情况,你不直接调用run方法的原因是你将调用该方法,而不是启动该线程。
答案 8 :(得分:1)
当我们使用start方法然后创建一个新线程,然后将为每个新线程执行run方法内的代码。
使用start方法为每个线程,Stack和本机堆栈创建两个堆栈。
但Run
方法只是调用execute
run
方法中的代码,因为运行方法调用不会创建不同的堆栈。
实施例
import java.util.concurrent.TimeUnit;
public class thread implements Runnable{
/**
* @param args
*/
public static void main(String[] args) {
Thread gg=new Thread(new thread());
Thread gg1=new Thread(new thread());
gg.run();
gg1.start();
/*gg.start();
gg1.start();*/
}
@Override
public void run() {
for(int i=0;i<5;i++)
{
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Hello..." + i);
}
}
}
答案 9 :(得分:0)
如果需要,我们可以调用run()
方法,但是如果我们调用run方法,它将只作为普通的Java方法运行。它我们称之为start(
),JVM
创建一个新线程,并在该线程上执行run方法。
答案 10 :(得分:0)
start()
和run()
方法用于运行线程。run()
方法只是一个普通的方法,它被用户覆盖,它将在当前线程上调用。
start()
方法间接运行run()
方法并创建新线程。
答案 11 :(得分:-1)
不同之处在于,如果我们通过start()
方法执行run方法,它会创建一个新线程,我们可以执行run方法,否则run()
方法将在JVM创建的线程中执行public static void main()
方法。这正是多线程的重点,在新线程上运行不同的操作。