• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Question about the IceCream Example in Max's Book at Chapter of Thread

 
Martin Ouyang
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In the Chapter of Thread,the author gives example codes :Child.java,IceCreamMan.java.There is an explanation about Child.java .
Notice that the Child thread check the condition of the dish.readyToEat variable in a while loop,not an if statement.The reason for this is the nature of how while loops interact with threads.As you know , athread could slice out of the CPU at any time--say ,after line 54 but before line 58.

But I think the thread enter the the while loop just for once,so if can also be used.
 
Mihai Radulescu
Ranch Hand
Posts: 918
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hallo,

Max uses there the spin look (the while look).The reason is as you said

As you know , athread could slice out of the CPU at any time--say ,after line 54 but before line 58.

, I presume that the while loop is between lines 54-58(you forget the line numbers).Let's try it with an example.
You have 2 threads waiting in the wait because the dish is not ready to eat(dish.readyToEat==false) and then they are awaked (notifyAll()) and no condition is tested - both threads access the dish in the same time, but it must be only one dish per thread(or kids) if you have look the iceman thread fills the dish fast enough but othrwise...
This is a race condition.
 
Max Habibi
town drunk
( and author)
Sheriff
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mihai is correct.

I don't have as much time as I would like to delve into this, so I'll try to be succinct. The basic difference not logic, but JVM implementation. When a Thread slices back in to the middle of an executing a while loop, the threads checks the original condition of the loop. It does not do this for if statements. Accordingly, while loops are to be preferred.

HTH,
M
 
Martin Ouyang
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
thanks Max and Mihai for replying.

But I think in this example ,it's impossible that two children would be waiting for one dish,because each dish is just belong to one child.
So I think the if statement is enough.
 
Mihai Radulescu
Ranch Hand
Posts: 918
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok Martin you're right

each dish is just belong to one child

BUT there is only one iceman(thread) and this thread can fill only one dish once - or if is easy for you it can serve only one client once.So the happiest case is when one client gets one valid object(one kid gets a dish with ice) and the rest get only empty non valid or better not ready objects (emtpy dishes).
This will be the happy case and nobody can guarantee about the thread running order(you may set some proprities but the thread scheduler/machine-CPU architecture/Operting system has the last word) so can happent that all the cleints(kids) gets only empty/non ready objects form them server(iceman).
I repeat this with if you use if you land on a race condition (Max has a describe this in his book) - your application state depends on the thread runing order.
I hope it help.If not(maybe i must improve my english skills) just search for "race condition under java".
 
Max Habibi
town drunk
( and author)
Sheriff
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Martin Ouyang:
thanks Max and Mihai for replying.

But I think in this example ,it's impossible that two children would be waiting for one dish, because each dish is just belong to one child.
So I think the if statement is enough.


You're correct: they're not waiting for one dish, but they are waiting for one ice cream man. Think of it this way.


Mai, one of the children, has seen that her ice cream bowl is empty, and she is patiently waiting. If Mia is using an if-statement, then she'll never go back and check her bowl again when she wakes up from her little 'nap': she'll just take another nap as soon as she wakes up. That is, she never executes the if-statement more than once.

However, If Mia is using an while-loop, then she'll always go back and check her bowl again. That is, she always executes the while-statement's condition when she wake up from taking a 'nap', and then goes back to taking a nap, or eats her ice-cream.

Make sense?
M
[ March 08, 2005: Message edited by: Max Habibi ]
 
Martin Ouyang
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As I read the IceCreamMan.java again,I believe that the children is waiting for dish .Please read the source segment of IceCreamMan.java as follows.The 5th line shows the synchronic lock is on dish.
[CODE]
1 private void serveIceCream(){
2 IceCreamDish currentDish = (IceCreamDish)dishes.get(0);
3 if(currentDish == null) return;
4 if (Math.random() > 0.5) delay();
5 synchronized(currentDish){
6 currentDish.readyToEat = true;
7 System.out.println("IceCreamMan : notify client that ice cream is ready");
8 currentDish.notifyAll();
9 dishes.remove(currentDish);
10 }
11 }
[CODE]
 
Martin Ouyang
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm sorry that the code pasted is not easy to read.I paste the code again.


And let me give some supplementary explanation of my opinion.
When the 8th line is excuted , the just one child waiting for the dish awakes.Since currentDish.readyToEat is already true,it is unnecessary to check currentDish.readyToEat is true or not again.
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 12014
220
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Martin,

The Sun JavaDoc comments for wait say, in part:

A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied. In other words, waits should always occur in loops, like this one:


This possibility of spurious awakening was not mentioned in prior versions of the JavaDoc (that I am aware of), however it has been described in item 50 of Joshua Bloch's Effective Java Programming Language Guide, where he states the information above, and says that although spurious wakeups are not covered in the JLS, "many JVMs use threading facilities in which spurious wakeups are known to occur, albeit rarely [Posix, 11.4.3.6.1]".

So even in those cases where only one client can ever wake up, you still need a while loop, just in case you happen to be deploying on a JVM that suffers from spurious wakeups.

Regards, Andrew
[ March 09, 2005: Message edited by: Andrew Monkhouse ]
 
Martin Ouyang
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I got it, thank you very much Andrew.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic