В чем разница между 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();
}

14 ответов


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

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


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


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


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

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


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

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

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

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


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


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

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


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


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

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

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

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

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

и что значит r.run() сделать?

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


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

r.run() метод вы обеспечить библиотека называть на новый поток.


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

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

public class B extends A implements Runnable{...

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

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

взгляните на исходный код start() метод нить класс!--16-->

 /**
     * 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 выполняет этот собственный метод.


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

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

ex.:

`

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

`


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

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

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


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

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

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