2008-11-04 4 views
105

Когда вы звоните в Java thread.run() вместо thread.start()?Когда вы вызываете java-поток thread.run() вместо thread.start()?

+45

Когда Я Thread.start() метод? :) – 2008-11-04 18:31:57

+3

@blank. Ответ просто: `t.run()`, когда вы хотите запустить задачу `t` в текущем потоке и` t.start() `, когда вы хотите запустить` t`` на тему `` `` `` `` `или вы запрашиваете фактические варианты использования? – Pacerier 2014-09-26 02:24:52

+1

Когда вы идиот и хотите потратить час на отладку многопоточного кода, чтобы понять позже, что вы должны просто называть` start() `! Как и я ... Этот метод должен быть не публичным! – 2017-02-23 15:30:00

ответ

109

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

9

Позвоните по телефону thread.start(), в свою очередь позвоните по телефону thread.run(). Не могу придумать случай, когда вы хотите обходить thread.start() и перейти непосредственно к thread.run()

+3

Во время тестирования это единственный законный случай, о котором я могу думать. В противном случае содержимое run() должно быть в отдельном методе, который вызывается при запуске или другими способами. – 2008-11-04 18:33:36

93

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

+23

«Никогда» слишком сурово. Может быть, не всегда нужен новый поток и все еще выполняйте код? – Tomalak 2008-11-04 18:51:12

+4

Возможно, но в этом случае было бы бесполезно расточительно создавать новую тему только для вызова метода run(). Лучше создать Runnable impl и запустить этот поток в потоке или построить и начать с ним новый Thread. – 2008-11-04 19:20:34

+0

Абсолюты, как правило, слишком сильны, но с другой стороны, правила нарушаются. Я считаю, что держать его ясным и простым является лучшим, особенно для начинающих программистов. Кроме того, этот случай является довольно сухим. Скотт Бэйл прибил его, когда предложил использовать Runnable. – 2008-11-04 20:49:26

5

Если вы хотите, чтобы он работал синхронно. Вызов метода run фактически не даст вам многопоточности. Метод start создает новый поток, который вызывает метод run.

27

Взятые формы в Code Style Java threads FAQ:

Q: В чем разница между начать потока() и запустить() методы?

A: Отдельные методы start() и run() в классе Thread предоставляют два способа создания потоков программ. Метод start() запускает выполнение нового потока и вызывает метод run() . Метод start() немедленно возвращается, и новый поток обычно продолжается до тех пор, пока не будет запущен метод ( ).

Метод run() класса Thread ничего не делает, поэтому подклассы должны переопределить метод с кодом выполнить во втором потоке. Если поток создается с помощью аргумента Runnable , то метод run() 0 (строка) потока (thread) ( ) выполняет метод run() для объекта Runnable в новом потоке .

В зависимости от характера многопоточной программы, вызывая темы Run() метод непосредственно может дать ту же результата, как вызов через начало() метода, но в последнем случае код фактически выполняется в новый поток .

3

Если вы хотите выполнить содержимое run(), как и любой другой метод. Не начинать тему, конечно.

3

Предполагая, что вы знаете использование метода запуска и запуска, то есть синхронное и асинхронное; метод run можно использовать только для проверки функциональности.

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

2

По крайней мере, в JVM 1.6., Есть немного проверки и запуска называется изначально:

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

Это уже упоминалось, но только, чтобы быть ясно: создание нового объекта Thread только назвать это запустить() метод неоправданно дорого и должен быть крупным красным флагом. Было бы намного лучше, более развязанный дизайн для создания Runnable impl и либо (a) call - это метод run() напрямую, если это желаемое поведение, или (b) построить новый Thread с этим Runnable и запустить Thread ,

Еще лучше, чтобы еще больше развязать, ознакомьтесь с интерфейсом и каркасом Executor в JDK 5 и новее. Это позволяет вкратце отделить выполнение задачи (экземпляр Runnable) от , как выполняется (реализация Executor, которая может выполнять Runnable в текущем потоке в новом потоке, используя существующий поток из пул и многое другое).

9

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

Метод Thread 'run() метод ничего не делает, поэтому подклассы должны переопределять метод с кодом для выполнения во втором потоке. Если Thread создается с помощью аргумента Runnable, то метод run() потока выполняет вместо этого метод объекта Runnable в новом потоке.

В зависимости от характера вашей потоковой программы вызов метода Thread run() напрямую может дать тот же вывод, что и вызов через метод start(), но в последнем случае код фактически выполняется в новом потоке.

reference

7

Если вопрос был - «почему метод резьб вызывается вместо метода выполнения непосредственно», то я ответил с примерами кода ниже. Надеюсь, что это прояснится. В приведенном ниже примере:

/* 
By calling t1.start(), 
we are getting the main calling thread returned immediately 
after the t1.start() called and is ready to proceed for other 
operations.And the thread t1 starts executing the run method of the object r. 
Hence the the output will be: 

     I am the main thread , i created thread t1 and had it execute run method, which is currently looping from 0 to 1000000 

     I am done executing run method of testThread 

*/ 


/* If we call t1.run() instead of t1.start(), (just replace t1.start() with t1.run() in the code for testing) 
its like a regular method call and the main thread will not return until the run method completes, 
hence the output will be: 

     I am done executing run method of testThread 

     I am the main thread , i created thread t1 and had it execute run method, which is currently looping for i to 1000000 

*/ 


class testThread implements Runnable{ 

public void run() 
{ 
    for(int i=0;i<1000000;i++){} //a simple delay block to clarify. 

    System.out.println("I am done executing run method of testThread"); 

} 
} 

public class mainClass{ 

    public static void main(String [] args) 
    { 
      testThread r = new testThread(); 
      Thread t1 = new Thread(r); 
      t1.start(); /* Question is: can we call instead t1.run() */ 
      System.out.println("I am the main thread , i created thread t1 and had it execute run method, which is currently looping for i to 1000000"); 

    } 
} 
23

thread.run() Выполнение не создает новый Thread, в котором ваш код запускается на выполнение. Он просто выполняет код в текущем потоке, из которого вызывается код thread.run().

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

В сущности:

однотридового программирование → прямой вызов run() метода

программирования

многопоточной → Вызова метода start()

Кроме того, как друг упомянули , «тестирование», по-видимому, является единственным целесообразным случаем, когда вы можете вызывать run() непосредственно из вашего кода.

2

Просто примечание к замечательным замечаниям: иногда вы пишете многопоточный код, который использует метод «запуска» для запуска разных потоков. Вы найдете это намного проще, если вы используете «Выполнить» (вместо «запуска) для отладки, так как это делает код для запуска синхронно и отладку намного проще.

-1
public class TestClass implements Runnable { 
    public static void main(String[] args) { 
     TestClass tc = new TestClass(); 

     Thread t1 = new Thread(tc); 
     System.out.println("Before Starting Thread " + Thread.currentThread().hashCode()); 
     t1.start(); 
     System.out.println("After Starting Thread " + Thread.currentThread().hashCode()); 
    } 

    @Override 
    public void run() { 
     System.out.println("TestClass Run method is Running with thread " + Thread.currentThread().hashCode());   
    } 
} 
Смежные вопросы