multithreading - Java threads - start() and run() - lost line in console -


why "taskimpl run()" in scenario 1 below missing ?

scenario 1: if line marked 1. before line marked 2. shown in console:

taskimpl run()
threadimpl run()
threadimpl run()
finished

scenario 2: if line marked 2. before line marked 1. shown in console:

taskimpl run()
taskimpl run()
threadimpl run()
threadimpl run()
finished

my code :

public class threadtest {     public static void main(string[] args)      {         thread t1 = new threadimpl();         thread t2 = new thread(new taskimpl());          t1.start();         t2.start();          t1.run();   // 1.         t2.run();   // 2.           try {             thread.sleep(5000);         } catch (interruptedexception e) {             // todo auto-generated catch block             e.printstacktrace();         }          system.out.println("finished");     } }  class threadimpl extends thread {     @override     public void run() {         try {             thread.sleep(2000);             system.out.println("threadimpl run()");         } catch (interruptedexception e) {             // todo auto-generated catch block             e.printstacktrace();         }     } }  class taskimpl implements runnable {     @override     public void run() {         try {             thread.sleep(1000);             system.out.println("taskimpl run()");         } catch (interruptedexception e) {             // todo auto-generated catch block             e.printstacktrace();         }     } } 

as can see in implementation of thread#run run method of target (the thread implementation/subclass should run in thread) called if target not null:

@override public void run() {     if (target != null) {         target.run();     } } 

now info: if thread has done job calls private exit method sets target null (*):

private void exit() {     // [omitted code lines]      /* aggressively null out reference fields: see bug 4006245 */     target = null;      // [omitted code lines] } 

so if called start on thread , has done job, can't call run again ... can, won't much.

now let's @ first version of code:

t1.start(); -> starts thread; takes @ least 2 seconds finish t2.start(); -> starts thread; takes @ least 1 second finish  t1.run(); -> blocks main thread; takes @ least 2 seconds finish t2.run(); -> called after `t1.run()` finished; 

so can see, t2.run() run @ least 2 seconds after t2.start() because t1.run() blocks method call. t2 (from t2.start()) finished , set target null t2.run() fails target != null check , "nothing".

now second version:

t1.start(); -> starts thread; takes @ least 2 seconds finish t2.start(); -> starts thread; takes @ least 1 second finish  t2.run(); -> blocks main thread; takes @ least 1 seconds finish t1.run(); -> called after `t2.run()` finished; 

here t2.run() can run before t2 t2.start() have finished "sleep" target still set correctly.
, t1.run() has no problem, because directly calls overriden run method of threadimpl, doesn't need pass check. , wouldn't have problem pass anyway, because t2.run() sleeps 1 second, t1 t1.start() still sleeps second , target still set.
why "full" output.

i hope explanation clear , understand cause different output :).

(*) please mind behavior vary in other java environments. oracles version , openjdk doing that.


Comments