Какая разница между Thread start() и Runnable run()

Скажем, у нас есть эти две 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();
}

Ответ 1

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

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 внутри, чтобы выполнить его в этом новом потоке.

Ответ 2

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

Ответ 3

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

Ответ 4

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

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

Ответ 5

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

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

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

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

Ответ 6

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

Ответ 7

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

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

Ответ 8

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

Ответ 9

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

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

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

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

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

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

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


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

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

Ответ 10

Точки, которые созданы членами, все в порядке, поэтому я просто хочу что-то добавить. Дело в том, что JAVA не поддерживает Multi-inheritance. Но что есть, если вы хотите получить класс 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{...

Ответ 11

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

Если вы вызываете метод start() в потоке, виртуальная машина Java вызовет метод run(), а два потока будут выполняться одновременно - Current Thread (main() в вашем примере) и Other Thread (Runnable r1 в вашем пример).

Посмотрите исходный код метода start() в класс темы

 /**
     * Causes this thread to begin execution; the Java Virtual Machine
     * calls the <code>run</code> method of this thread.
     * <p>
     * The result is that two threads are running concurrently: the
     * current thread (which returns from the call to the
     * <code>start</code> method) and the other thread (which executes its
     * <code>run</code> method).
     * <p>
     * It is never legal to start a thread more than once.
     * In particular, a thread may not be restarted once it has completed
     * execution.
     *
     * @exception  IllegalThreadStateException  if the thread was already
     *               started.
     * @see        #run()
     * @see        #stop()
     */
    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();

В вышеприведенном коде вы не можете вызвать вызов в метод run().

private native void start0() отвечает за вызов метода run(). JVM выполняет этот собственный метод.

Ответ 12

В первом случае вы просто вызываете метод run() объектов r1 и r2.

Во втором случае вы фактически создаете 2 новых темы!

start() вызовет run() в какой-то момент!

Ответ 13

Предположим, что вы являетесь менеджером гостиницы по имени Тема. Таким образом, в основном то, что делает t1.run(), заключается в том, что он заставляет вас выполнять все задачи самостоятельно, в то время как ваши другие помощники Thread сидят без дела, перелистывая большие пальцы. Но если вы используете t1.start(), одному из ваших помощников назначается какая-то задача, а затем он/она начинает выполнять эту задачу, а вы выполняете задание, которое вы должны делать, это управление помощниками.

Источник: Программирование Интервью: Темы в операционной системе (Java) Часть 2 Многопоточность

Ответ 14

Вызов метода Start() запускает метод переопределения расширенного класса Thread и реализует интерфейс Runnable.

Но, вызывая run(), он ищет метод run, но если класс реализует интерфейс Runnable, он вызывает метод переопределения run() класса Runnable.

напр.:

'

public class Main1
{
A a=new A();
B b=new B();
a.run();//This call run() of Thread because run() of Thread only call when class 
        //implements with Runnable not when class extends Thread.
b.run();//This not run anything because no run method found in class B but it 
        //didn't show any error.

a.start();//this call run() of Thread
b.start();//this call run() of Thread
}

class A implements Runnable{
@Override
    public void run() {
            System.out.println("A ");
    }
}

class B extends Thread {

    @Override
    public void run() {
            System.out.println("B ");
    }
}

'

Ответ 15

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

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

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