Thanks Tommy for your quick answer. Please, could you read my questions/comments to your comments.
I wrote them in blue colour with (CAPITAL LETTERS) to find them easier.
public class Race
{
public static void main(
String[] args)
{
Horse h = new Horse();
Thread t1 = new Thread(h, "Andi");
Thread t2 = new Thread(h, "Eyra");
new Race().go(t2); //(1) - This call will always execute first.
(I AGREE)
t1.start(); // (2) - This call will execute second, but doesn't mean t1 thread is execute just t1 is alive in state of execution.
/
(I AGREE, BUT IT IS IN THIS POINT WHERE I GET CONFUSED. THERE IS NOT
// GUARANTEED THAT IT WILL RUN IMMEDIATELY, BUT WILL IT RUN TO COMPLETION?
// IF YOUR ANSWER TO MY QUESTION IS YES, THE BIG QUESTION ABOUT IF THE OPTION "E"
// IS A POSSIBILITY CAN BE ANSWER RIGHT NOW:
//
// E. The output could be: "Eyra ", followed by an exception.
//
// I THINK THIS OPTION NEEDS THE WORD "Andi " SOMEWHERE IN THE OUTPUT TO BE CORRECT
// AM I RIGHT?
t2.start(); // (3) - This call will execute third, but doesn't mean t2 thread is execute just t2 is alive in state of execution.
//
(I AM NOT SURE WHAT YOU MEANT WHEN YOU SAY ...just t2 is alive in state of execution.
// I THINK THIS IS THE CALL WHICH WILL THROW THE EXCEPTION, BECAUSE THERE HAVE ALREADY BEEN
// A CALL TO t2.start() (WELL, TO t.start()) IN THE METHOD go() IN (1)
// AM I RIGHT?)
}
void go(Thread t) // No LOCK is acquired for this method so, any thread can jump and interrupt t thread
{ //
(I AGREE, BUT AS THE CODE STANDS THERE IS NOT A POSSIBLE INTERRUPTION
// AM I RIGHT?)
System.out.println("go before"); //This line execute sequentialy and print out
t.start(); // This line started the thread of execution, but not guaranteed it will run.
//
(BUT WILL IT RUN TO COMPLETION?
// AM I RIGHT?)
System.out.println("go after"); //This line execute sequentialy and print out
}
}
class Horse implements Runnable
{
public void run()
{
System.out.print(Thread.currentThread().getName() + " ");
}
}
/*
1st run:
go before
go after
Eyra Exception in thread "main"
Andi java.lang.IllegalThreadStateException
at java.lang.Thread.start(Unknown Source)
at Race.main(Race.java:10)
new Race().go(t2); //(1) - Execute first calling the go(t2) method
//(1a) - The go(t2) method is executed
//(1b) t.start(); - Could execute first or second or third or not executed at all.
//
WHAT DO YOU MEAN WHEN YOU SAY: ... or not executed at all?
// IS THERE ANY POSSIBILITY THAT THE run() METHOD IN THREAD t2 "Eyra " WILL
// NOT BE EXECUTED?
//This thread guaranteed to execute only the go() method acquired a LOCK
//on the go() method with a Synchronized keyword. Otherwise, t1 or t2 code
//lines below run next.
//
(I AGREE, BUT THE CALL TO t.start() IS DONE AT THIS POINT, SO
// THE THREAD t2 IS AN ALIVE THREAD AND IT WILL RUN TO COMPLETION
// AM I RIGHT?
t1.start(); //(2) - Execute first or second or third or won't execute at all.
t2.start(); //(2) - Execute first or second or third or won't execute at all.
//
I AM SORRY TO REPEAT THE SAME QUESTION, BUT HERE I STILL
// CANNOT UNDERSTAND HOW A CALL LIKE t1.start() IN THE MAIN THREAD WILL
// NOT BE EXECUTED?
// ALL THESE CALLS ARE IN THE MAIN METHOD AND THEY WILL BE EXECUTED
// SEQUENTIALLY INSIDE THE MAIN THREAD WHEN IT IS RUNNING
// AM I RIGHT?
Based on the result above you can see that t2 is executed twice before t1 does. t2.start() or t.start()
execute FIRST and t1.start(); execute SECOND and
print out "Andi" before the rest of exception message
print out.
So this conclude and confirm that:
E. The output could be: "Eyra ", followed by an exception.
(AND THIS IS WHAT I CAN NOT UNDERSTAND, IF THREAD t1 PRINTED OUT AS YOU SAID ABOVE (IN BOLD RED STYLE),
THE WORD "Andi " IS MISSING IN THIS OUTPUT, IT MUST APPEAR SOMEWHERE IN THE OUTPUT TO MAKE THE OPTION CORRECT.
AM I RIGHT?)
---------
2nd run:
go before
go after
Eyra Exception in thread "main" java.lang.IllegalThreadStateException
Andi
at java.lang.Thread.start(Unknown Source)
at Race.main(Race.java:10)
(THE WORD "Andi " APPEARS AGAIN IN THE OUTPUT)
- This scenario t.start() or t2.start() started first or second, and t.start() didn't start at all. From
this experiment you can confirm that no Thread is guaranteed to run.
(AS YOU CAN SEE IN THIS OUTPUT THREAD t2 PRINTED OUT ITS NAME "Eyra ",
THREAD t1 PRINTED OUT ITS NAME "Andi " TOO, AND THE MAIN THREAD HAS THROWN THE EXCEPTION)
---------
3rd run:
go before
go after
Eyra
Andi Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Unknown Source)
at Race.main(Race.java:10)
- In this case t.start() or t2.start() execute FIRST and followed t1.start(), and finally an exception
thrown by t.start() or t2.start().
---------
4th run:
go before
go after
Eyra Exception in thread "main" java.lang.IllegalThreadStateException
Andi
at java.lang.Thread.start(Unknown Source)
at Race.main(Race.java:10)
- This scenario similar to 1st run except the "Andi" print out in different place within the exception
message print out.
Because is no LOCK on an Object any thread can jump in and execute while other thread is running
(i.e t.start() or t2.start()) interrupted by t.start() despite the FACT that each thread will
run to it completion and it is in this case.
(I DO NOT REALLY UNDERSTAND WHAT YOU MEAN WITH THIS SENTENCE. I CAN SEE
THAT THE run() METHOD IS NOT SYNCHRONIZED, SO SEVERAL THREADS CAN JUMP IN AND EXECUTE
ITS CODE CONCURRENTLY, BUT WHAT YOU MEAN WITH THE REST OF THE SENTENCE PARTICULARLY
WHERE YOU HAS USED THE WORD "INTERRUPTED". IT IS NOT CLEAR TO ME.)
The running thread is interrupted by other thread, but it will running until complete it execution once
it has a chance enter the running state.
(WHEN YOU SAY "INTERRUPTED" YOU MEAN THAT THE RUNNING THREAD GOES TO RUNNABLE
STATE AND ANOTHER THREAD GOES TO RUNNING. AM I RIGHT?)
So this conclude and confirm that:
E. The output could be: "Eyra ", followed by an exception.
Recap from K & B book page 766.
Besides those three, we also have the following scenarios in which a thread might
leave the running state:
¦ The thread's run() method completes. Duh.
(OK, THAT MEANS THAT t1 WILL PRINT "Andi ")
¦ A call to wait() on an object (we don't call wait() on a thread, as we'll
see in a moment).
(OK, BUT IN THIS CODE THERE ARE NOT CALLS TO wait() ON ANY OBJECT)
¦ A thread can't acquire the lock on the object whose method code it's
attempting to run.
(OK, BUT THIS IS NOT POSSIBLE IN THIS CODE)
¦ The thread scheduler can decide to move the current thread from running
to runnable in order to give another thread a chance to run. No reason is
needed—the thread scheduler can trade threads in and out whenever it likes.
(OK, BUT ALL ALIVE THREADS WILL GET CHANCES TO RUN TO COMPLETION
AM I RIGHT?)
In summary, the thread scheduler is the controller that governs the execution
of threads in and out whenever it decided to.
(I AGREE)
If you run the code above on different machine it will behaves and prints out results
differently. There is nothing in order to which thread will execute first, it depends on
the VM Thread Scheduler to chooses which thread to run.
(I AGREE)
*/
Please, if you have time, could you clarify me these points?
Once again, thank you very much for your time. I have tried to explain myself as clear as I can. I am sorry if I did not write something incorrect, but English is not my tongue language