aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes thread question from sun's Free Proficiency Assessment System Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "thread question from sun Watch "thread question from sun New topic
Author

thread question from sun's Free Proficiency Assessment System

Ruz Li
Greenhorn

Joined: Nov 29, 2007
Posts: 10
how to solve the following thread question:

Given:
5. class NoGo implements Runnable {
6. private int i;
7. public synchronized void run() {
8. if (i%10 != 0) { i++; }
9. for(int x=0; x<10; x++, i++)
10. { if (x == 4) Thread.yield(); }
11. System.out.print(i + " ");
12. }
13. public static void main(String [] args) {
14. NoGo n = new NoGo();
15. for(int x=0; x<101; x++) { new Thread(n).start(); }
16. }
17. }
Which is true?
a The output can never contain the value 10.
b The output can never contain the value 30.
c The output can never contain the value 297.
d The output can never contain the value 820.
e The output can never contain the value 1010.


SCJP, SCWCD
Sanjay Singhaniya
Greenhorn

Joined: Feb 21, 2009
Posts: 25
Only value 10 will be printed.

So the correct answers are b,c,d,e.
Morteza Manavi-Parast
Ranch Hand

Joined: Dec 25, 2008
Posts: 66
No. The correct answer is: (c)
"The output can never contain the value 297"

Explanation:

First of all note that even though the i in the NoGo is an instance variable, all the thread start with the same object (n), so i is shared between 100 thread objects.

As you see at the for loop there is a yield method, and we know that there is no guarantee that a thread run this method and actually yield and go from running state to runnable, so to better understand what the code does, I will explain it in two situation (which both is possible at runtime)

1) Threads do not yield
In this case we basically ignore the Thread.yield() line and interpret the code as this line commented. The initial value of i is 0 so the expression i%10 !=0 evaluates to false, so i incremented in the for loop 10 times, then 10 will be printed. Well, same scenario for the rest of threads, we'll have 20, 30, 40,....., 1000. (Since we have 100 thread and each increment the i for 10 times so 10x100=1000) and in all of these the first if condition always evaluate to false.

1) Threads do yield
Well, this one is a bit tricky. For the first thread, when thread is going to yield, the i value is 4 since x and i incremented along together equivalently. Ok, thread yields, next thread will come to play with the value of i==4. So this time the first if run and i become 5 and when entering the loop, we have 4 more increments for i to make the value 9 and x==4 then thread yield again and next thread increment the i value in the if to 10 and again 4 more....
The key point is from x=0 to x=4 we have 5 iteration but the increment statement run 4 times, so basically the first if compensate the fifth increment and make the value of the i something divisible by 10. After all the threads yield the first thread go to running state again and execute the 5 more loop iteration it has and print the value of i. So again, we never come across a value of i which is not divisible by 10.

Hope this makes sense... and one last thing: it's a good idea to run the code at least once before answering other's questions in here!









SCJP 6
Sanjay Singhaniya
Greenhorn

Joined: Feb 21, 2009
Posts: 25
My bad. I will take care next time.
I shouldn't have sounded so confident in answering the question.
Sanjay Singhaniya
Greenhorn

Joined: Feb 21, 2009
Posts: 25
I guess this has to do more with synchronzed keyword than anything else. Since current executing thread is running a sunchronized run() method, its yield would not release the lock and the same thread would be selected to run as other threads are waiting for the same lock it is holding.
Sanjay Singhaniya
Greenhorn

Joined: Feb 21, 2009
Posts: 25
To understand my point, please replace Thread.yield() with Thread.Sleep(1000).

To convince yourself that your argument is incorrect, please try following code.

Ruben Soto
Ranch Hand

Joined: Dec 16, 2008
Posts: 1032
I think that is correct (a thread will not give up any locks it has acquired when yielding.) So this program should print all multiples of 10 for that reason.


All code in my posts, unless a source is explicitly mentioned, is my own.
Morteza Manavi-Parast
Ranch Hand

Joined: Dec 25, 2008
Posts: 66
Yes, that's right. I was totally ignored that Synchronized keyword in the run method while I was explaining that code. I think I should have been on cheap drugs!

So, yea the thread yields and since it has the lock other threads will keep waiting state so the same thread will go back to the running state. So basically my first condition "Threads do not yield" will always happen in this case which brings back those results which have mentioned.

Thanks,
Sanjay Singhaniya
Greenhorn

Joined: Feb 21, 2009
Posts: 25
Just a note : While giving SCJP exams, if there seems to be complicated logic then always check whether there are some simple Java rules at work.
As my code snippet shows, if the thread are indeed interleaved then the numbers printed need not be either multiple of 5 or 10.
Ruben Soto
Ranch Hand

Joined: Dec 16, 2008
Posts: 1032
Sanjay Singhaniya wrote:Just a note : While giving SCJP exams, if there seems to be complicated logic then always check whether there are some simple Java rules at work.
As my code snippet shows, if the thread are indeed interleaved then the numbers printed need not be either multiple of 5 or 10.

Sanjay, your example is nice, but it is completely different from the original example because the run method is not synchronized. When you have multiple threads and no synchronization, pretty much any result is possible (synchronization just limits the possible outcomes slightly )
Sanjay Singhaniya
Greenhorn

Joined: Feb 21, 2009
Posts: 25
I killed some more time and made the threads to yield.



And the output is :

15 45 65 100 106 117 143 169 175 181 187 193 199 205 211 217 228 249 265 271 277
303 309 320 330 345 351 357 363 369 375 386 392 398 419 435 446 452 458 464 470
476 492 548 559 565 571 577 598 609 615 626 637 643 649 655 661 667 673 679 690
696 747 753 759 770 776 812 818 849 855 861 867 873 884 890 896 907 923 934 940
950 956 962 968 979 985 991 1017 1023 1029 1035 1041 1047 1053 1059 1065 1085 1
091 1097 1103

As the output shows that still not all numbers are multiples of 2 or 5 or 10.
Ruben Soto
Ranch Hand

Joined: Dec 16, 2008
Posts: 1032
That's a nice program, Sanjay. I don't think we should be using AtomicInteger for the SCJP though.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: thread question from sun's Free Proficiency Assessment System