Почему мы не можем напрямую вызвать метод run()?

Если метод start() потока внутренне вызывает метод run(), то почему бы нам напрямую не вызвать метод run() в нашем коде? Каковы проблемы, связанные с этим?

Ответ 1

Метод start гарантирует, что код запускается в новом контексте потока. Если вы вызываете run напрямую, это будет похоже на обычный вызов метода, и он будет работать в контексте текущего потока, а не нового. Метод start содержит специальный код для запуска нового потока; run, очевидно, не обладает этой способностью, потому что вы не включили его, когда вы написали метод run.

Ответ 2

Когда мы вызываем метод start() для объекта потока, метод start() запускает новый поток выполнения, создавая новый стек вызовов для потока. Начало() заставляет этот поток начинать выполнение, а Java Виртуальная машина вызывает метод run() этого потока. Что, если мы будем называть run() вместо start():

Хотя это законно, но метод run() переходит в текущий стек вызовов вместо создания нового стека вызовов.

Например, если текущий выполняемый метод является основным, тогда созданный стек вызова:

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() создал новый стек вызовов) Call Stack - главная тема

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() переходит в текущий стек вызовов

Ответ 3

Вызов run выполняется синхронно; тогда как разрешение JVM на вызов run через start позволит асинхронному выполнению кода.

Вызов run напрямую часто бывает полезен в ситуации тестирования, когда можно избежать потоковой передачи.

Ответ 4

Потому что start() будет делать это как отдельный поток. Если бы вы просто вызвали run(), это было бы частью вашего потока (т.е. Вызова функции).

И, учитывая, что ваш поток может быть бесконечным циклом, ожидающим работы, это было бы плохо.

Ответ 5

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();
    }
}

Скопируйте и вставьте над кодом... затем запустите его,, и посмотрите разницу в выходе.

В основном run() будет просто выводить свое тело в контексте текущего потока (который здесь является основным) Но, start() сделать вызов ОС для создания нового потока. start() вызовет метод run() в контексте вновь созданного потока.

Ответ 6

Вызов метода запуска напрямую запустит этот код в основном потоке. Тогда это похоже на то, что ваша программа будет иметь только один поток (основной поток, заданный O.S).

Если вы вызываете метод start, который вызывает диспетчер потоков уровня драйвера для создания потока для вас, а оттуда вызывается функция запуска. И, следовательно, ваш метод запуска будет выполняться в отдельном потоке. Не в основной теме.

Ответ 7

Идея потока состоит в том, чтобы создавать новый стек каждый раз, когда запускается новый поток.

Вызов метода 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        5        1        2        3        4        5

Ответ 8

Хотя вызов run() напрямую является законным, но он победит цель многопоточности. Нить работает независимо, имея собственный стек вызовов, если мы не используем метод start(), чем исполняемый стек для этого оператора, будет текущим стеком, через который выполняется этот оператор (метод main() в большинстве случаев). Это приведет к победе над задачей запуска задания одновременно, в то время как наш метод main() или, другими словами, выполняется первичный стек.