Первый пример: Нет нескольких потоков. Оба выполняются в одном (существующем) потоке. Нет создания потока.
R1r1=newR1(); R2r2=newR2();
r1 и r2 - это всего лишь два разных объекта классов, которые реализуют Runnable интерфейс и, таким образом, реализуют run() метод. При вызове r1.run() вы выполняете его в текущем потоке.
Второй пример: два отдельных потока.
Threadt1=newThread(r1); Threadt2=newThread(r2);
t1 и t2 являются объектами класса Thread. Когда вы вызываете t1.start(), он запускает новый поток и вызывает run() метод r1 внутренне, чтобы выполнить его в этом новом потоке.
Ответ 2
Если вы просто вызываете run() напрямую, это выполняется в вызывающем потоке, как и любой другой вызов метода. Thread.start() требуется фактически создать новый поток, чтобы run метод runnable выполнялся параллельно.
Ответ 3
Разница в том, что Thread.start() запускает поток, который вызывает run() метод, в то время как Runnable.run() просто вызывает run() метод в текущем потоке.
Ответ 4
The difference is that when program calls start() method, a new thread is created and code inside run() is executed in the new thread: while if you call run() method directly, no new thread will be created and code inside run() will execute in the current thread directly.
Another difference between start() and run() in Java thread is that you cannot call start() twice. Once started, second start() call will throw IllegalStateException in Java while you can call run() method several times since it's just an ordinary method.