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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

  /** * Causes this thread to begin execution; the Java Virtual Machine * calls the run method of this thread. * 

* The result is that two threads are running concurrently: the * current thread (which returns from the call to the * start method) and the other thread (which executes its * run method). *

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

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

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

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

Но, вызвав run (), он ищет метод run, но если class, реализующий интерфейс Runnable, затем вызывает метод run () override метода 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 "); } } 

`

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

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

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

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

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

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

  • В чем разница между ConcurrentHashMap и Collections.synchronizedMap (Карта)?
  • Нужно ли защищать доступ для чтения к контейнеру STL в многопоточной среде?
  • Невозможно создать кэшированный пул streamов с ограничением размера?
  • ОЖИДАНИЕ на sun.misc.Unsafe.park (родной метод)
  • Java Fork / Join vs ExecutorService - когда использовать какой?
  • Является ли это идиоматическим пулом рабочих streamов в Go?
  • Atomic UPDATE .. SELECT в Postgres
  • Есть ли способ для нескольких процессов совместно использовать прослушивающий сокет?
  • Возможна ли память в ConcurrentBag?
  • Swing - Обновить ярлык
  • Какой алгоритм параллельной сортировки имеет лучшую среднюю производительность?
  • Давайте будем гением компьютера.