为什么我们不能直接调用run()方法?

时间:2011-01-28 16:01:16

标签: multithreading java-me

如果线程的start()方法在内部调用run()方法,为什么我们不直接在代码中调用run()方法?这样做涉及哪些问题?

8 个答案:

答案 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()方法或主堆栈运行时,这将无法同时运行作业。

相关问题