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
Post a Comment