В чем разница между Thread start () и Runnable run () - PullRequest
204 голосов
/ 20 декабря 2011

Скажем, у нас есть эти два Runnables:

class R1 implements Runnable {
    public void run() { … }
    …
}

class R2 implements Runnable {
    public void run() { … }
    …
}

Тогда какая разница между этим:

public static void main() {
    R1 r1 = new R1();
    R2 r2 = new R2();

    r1.run();
    r2.run();
}

А это:

public static void main() {
    R1 r1 = new R1();
    R2 r2 = new R2();
    Thread t1 = new Thread(r1);
    Thread t2 = new Thread(r2);

    t1.start();
    t2.start();
}

Ответы [ 14 ]

290 голосов
/ 20 декабря 2011

Первый пример: Нет нескольких потоков. Оба выполняются в одном (существующем) потоке. Нет создания темы.

R1 r1 = new R1();
R2 r2 = new R2();

r1 и r2 - это просто два разных объекта классов, которые реализуют интерфейс Runnable и, таким образом, реализуют метод run(). Когда вы вызываете r1.run(), вы выполняете его в текущем потоке.

Второй пример: Два отдельных потока.

Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);

t1 и t2 являются объектами класса Thread. Когда вы вызываете t1.start(), он запускает новый поток и вызывает метод run() для r1 внутри, чтобы выполнить его в этом новом потоке.

89 голосов
/ 20 декабря 2011

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

65 голосов
/ 28 октября 2013

Разница в том, что Thread.start() запускает поток, который вызывает метод run(), тогда как Runnable.run() просто вызывает метод run() в текущем потоке.

30 голосов
/ 08 февраля 2016

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

Другая разница между start() и run() в потоке Java означает, что вы не можете дважды start() вызвать.После запуска второй start() вызов вызовет IllegalStateException в Java, в то время как вы можете вызывать метод run() несколько раз, поскольку это просто обычный метод.

22 голосов
/ 30 октября 2012

На самом деле Thread.start() создает новый поток и имеет собственный сценарий выполнения.

Thread.start() вызывает метод run() асинхронно, что изменяет состояние нового потока на Runnable.

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

Если вы используете Thread.run(), то вы вообще не используете функции многопоточности.

8 голосов
/ 02 октября 2014

invoke run() выполняется в вызывающем потоке, как и любой другой вызов метода. тогда как Thread.start() создает новый поток. invoking run() - это программная ошибка.

6 голосов
/ 28 октября 2013

Если вы выполняете run() в методе main, поток метода main вызовет метод run вместо потока, который требуется запустить.

Метод start() создает новый поток и длякоторый run() метод должен быть сделан

5 голосов
/ 27 декабря 2011
Код

Thread.start() регистрирует поток с помощью планировщика, а планировщик вызывает метод run().Кроме того, Thread является классом, а Runnable является интерфейсом.

4 голосов
/ 27 октября 2015

В большинстве из этих ответов отсутствует общая картина: между языком t.start() и r.run() разницы между *1001* и *1002* нет больше, чем между любыми двумя другими методами.

Они оба просто методы. Они оба запускают в потоке, который назвал их . Они оба делают то, что им было закодировано, и затем оба возвращаются, все еще в том же потоке, к своим вызывающим абонентам.

Самым большим отличием является то, что большая часть кода для t.start() является нативным кодом, в то время как в большинстве случаев код для r.run() будет чисто Java. Но это не большая разница. Код есть код. Родной код труднее найти, и труднее понять, когда вы его найдете, но он все еще просто код, который говорит компьютеру, что делать.

Итак, что делает t.start()? 1016 *

Создает новый собственный поток, организует, чтобы этот поток вызывал t.run(), а затем сообщает ОС, чтобы новый поток работал. Затем он возвращается.

А что делает r.run()? 1022 *

Самое смешное, что тот, кто задает этот вопрос, - тот, кто написал . r.run() делает то, что вы (т. Е. Разработчик, написавший это) разработали.


t.start() - это метод, который библиотека предоставляет для вызова вашего кода, когда вы хотите создать новый поток.

r.run() - это метод, который вы предоставляют для библиотеки для вызова в новой нити.

3 голосов
/ 21 января 2015

С пунктами, которые высказали участники, все в порядке, поэтому я просто хочу кое-что добавить. Дело в том, что JAVA не поддерживает мульти-наследование. Но что делать, если вы хотите получить класс B из другого класса A, но вы можете получить только из одного класса. Теперь проблема заключается в том, как «извлечь» из обоих классов: A и Thread. Поэтому вы можете использовать Runnable Interface.

public class ThreadTest{
   public void method(){
      Thread myThread = new Thread(new B());
      myThread.start;
   }
}

public class B extends A implements Runnable{...
...