如果线程的start()方法在内部调用run()方法,为什么我们不直接在代码中调用run()方法?这样做涉及哪些问题?
答案 0 :(得分:16)
start
方法确保代码在新的线程上下文中运行。如果你直接调用run
,那么它就像一个普通的方法调用,它将在当前线程的上下文中运行,而不是在新线程中运行。 start
方法包含触发新线程的特殊代码; run
显然没有这种能力,因为你在编写run
方法时没有包含它。
答案 1 :(得分:4)
当我们在线程对象上调用start()方法时,start()方法通过为线程创建一个新的调用堆栈来启动一个新的执行线程.start()使这个线程开始执行和Java虚拟机调用此线程的run()方法。 如果我们调用run()而不是start():
,该怎么办?虽然这是合法的,但run()方法进入当前调用堆栈而不是创建新的调用堆栈。
例如,如果当前正在执行的方法是main,则创建的调用堆栈为:
class MyThread extends Thread
{
public void run()
{
System.out.println("running");
}
}
public class ThreadDemo
{
public static void main (String[] args )
{
MyThread thread=new MyThread();
thread.start();
}
}
为新线程调用堆栈(start()方法创建了一个新的调用堆栈) 调用堆栈 - 主线程
class MyThread extends Thread
{
public void run()
{
System.out.println("running");
}
}
public class ThreadDemo
{
public static void main (String[] args )
{
MyThread thread=new MyThread();
thread.run();
}
}
run()方法不会为线程创建新的调用堆栈。 run()方法进入当前调用堆栈
答案 2 :(得分:3)
调用run
同步执行代码;而允许JVM通过run
调用start
将允许代码异步执行。
在可能希望避免线程化的测试情况下,直接调用run
通常是有益的。
答案 3 :(得分:2)
因为start()
会将其作为单独的线程执行。如果您只是致电run()
,那将是您的线程的一部分(即函数调用)。
而且,鉴于你的线程可能是一个等待工作的无限循环,那将是一个坏事。
答案 4 :(得分:2)
class A implements Runnable
{
public void run()
{
for( int i=0; i<5; i++)
{
System.out.println("Thread-A " +i + " Thread Name: " +Thread.currentThread().getName());
}
}
}
class B implements Runnable
{
public void run()
{
for( int i=0; i<5; i++)
{
System.out.println("Thread-B " +i + " Thread Name: " +Thread.currentThread().getName() );
}
}
}
class MyThread
{
public static void main(String [] args)
{
Thread t1 = new Thread(new A());
Thread t2 = new Thread(new B());
t1.run();
t2.run();
System.out.println("**********************************************************");
t1.start();
t2.start();
}
}
复制&amp;粘贴上面的代码...然后运行它,,,并查看输出的差异..
基本上run()只会在当前线程(这里主要是)的上下文中超越它的主体 但, start()调用OS来创建一个新线程。 start()将在新创建的线程的上下文中调用run()方法。
答案 5 :(得分:0)
直接调用run方法将在主线程中运行该代码。 然后就好像你的程序只有一个线程(即O.S给出的主线程)。
如果调用start方法,它将调用驱动程序层线程管理器为您创建一个线程,并从那里调用run函数。因此,您的run方法将在一个单独的线程中执行。不在主线程中。
答案 6 :(得分:0)
线程背后的想法是每次新线程开始运行时创建新堆栈。
从主线程调用run()方法,run()方法进入当前调用堆栈而不是新调用堆栈的开头。
如果直接调用run()方法,请解决此问题:
class TestCallRun2 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.print(i+" ");
}
}
public static void main(String args[]){
TestCallRun2 t1=new TestCallRun2();
TestCallRun2 t2=new TestCallRun2();
t1.run();
t2.run();
}
}
输出:
1 2 3 4 五 1 2 3 4 5
答案 7 :(得分:0)
尽管直接调用run()
是合法的,但它会破坏多线程的目的。一个线程通过拥有自己的调用堆栈来独立工作,如果我们不使用start()
方法,那么该语句的执行堆栈将是该语句运行的当前堆栈(main()
方法在大多数情况下案件)。在我们的main()
方法或主堆栈运行时,这将无法同时运行作业。