This week's book giveaway is in the Programmer Certification forum.
We're giving away four copies of OCP Oracle Certified Professional Java SE 21 Developer Study Guide: Exam 1Z0-830 and have Jeanne Boyarsky & Scott Selikoff on-line!
See this thread for details.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

thread question from sun's Free Proficiency Assessment System

 
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Greenhorn
Posts: 25
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Only value 10 will be printed.

So the correct answers are b,c,d,e.
 
Ranch Hand
Posts: 66
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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!








 
Sanjay Singhaniya
Greenhorn
Posts: 25
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
My bad. I will take care next time.
I shouldn't have sounded so confident in answering the question.
 
Sanjay Singhaniya
Greenhorn
Posts: 25
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 25
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
To understand my point, please replace Thread.yield() with Thread.Sleep(1000).

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

 
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Morteza Manavi-Parast
Ranch Hand
Posts: 66
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 25
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 25
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That's a nice program, Sanjay. I don't think we should be using AtomicInteger for the SCJP though.
 
When I was younger I felt like a man trapped inside a woman’s body. Then I was born. My twin is a tiny ad:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic