This week's book giveaway is in the Clojure forum.
We're giving away four copies of Clojure in Action and have Amit Rathore and Francis Avila on-line!
See this thread for details.
Win a copy of Clojure in Action this week in the Clojure forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Thread question in an example of Kathy and Bert Book

 
Richard Vagner
Ranch Hand
Posts: 108
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is a sample code from Kathy and Bert's certification book:



I tried to run this program on Windows xp with JDK1.5.0 and all I got is:

Waiting for calculation...
Waiting for calculation...
Waiting for calculation...

The line "System.out.println("Total is: " + c.total);" never gets executed.

Can anyone explain?
 
Mike Gershman
Ranch Hand
Posts: 1272
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The problem is that you moved one line , "calculator.start();", above the other calls to start(). This statement immediately starts a thread with Calculator's run() method from the main thread. Calculator.run() takes the lock on the Calculator object, counts from 0 to 99, issues a notifyAll() with no one waiting, and returns to main().

Only now do the "new Reader(calculator).start();" statements start 3 more threads that reach the "c.wait();" statement in run() and wait. Notice that these 3 threads synchronize on the Calculator object but never call the Calculator.run() method.

So, no one issues another notifyAll() on the Calculator object and the threads wait forever.

Now, see if you can explain the difference with "calculator.start();" back at the bottom of main().

[ December 27, 2004: Message edited by: Mike Gershman ]
[ December 27, 2004: Message edited by: Mike Gershman ]
 
Anand Ko
Ranch Hand
Posts: 79
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
- First the Calculator thread acquired the lock on the object.
- It will enter the for loop and notifyAll() is invoked. But there are no any threads waiting on that object.
- Once the lock is released. The other three threads starts executing each printing "Waiting for Calculation" and go in wait state. So the last statement never gets executed
 
Richard Vagner
Ranch Hand
Posts: 108
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks, Mike and Anand for your explanation.

Actually I did not "move one line , "calculator.start();", above the other calls". This is the exact code from Kathy and Bert's book page 533.

So I guess the code itself has an error? So the correct sequence should be




Thanks again.
 
Bert Bates
author
Sheriff
Posts: 8898
5
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Wow Richard!

You must have a very old copy of the book. I'm really sorry, that error was fixed a long time ago - maybe 2nd printing. In any case, your analysis is correct, move calculator.start() down.

- Bert

p.s. you can find the errata report on the Oborne website.
 
d stevenson
Greenhorn
Posts: 1
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Even if the calculator.start() line is moved below the Reader().start lines, does that guarantee that the example will work?

Once the main thread has created the 3 Reader threads and the Calculator thread, is it still not possible (theoretically, if not realistically) that the Calculator thread could run to completion before the 3 Reader threads have all called wait()?

(I've been away from Java since 2001 so I am probably missing something...)
 
Mike Gershman
Ranch Hand
Posts: 1272
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Even if the calculator.start() line is moved below the Reader().start lines, does that guarantee that the example will work?

Once the main thread has created the 3 Reader threads and the Calculator thread, is it still not possible (theoretically, if not realistically) that the Calculator thread could run to completion before the 3 Reader threads have all called wait()?


You are correct.

A complete solution would use the timed version of wait() and have some indicator of completeness to check besides the notifyAll(). According to the API, there are even "spurious wakeups", so you must always check whether the event you are waiting on has really occurred or you should just wait again.

This illustrates that while we are learning thread code for the exam, we should stick to proven patterns on the job. Solid asynchronous programming is hard to write and even harder to test.

Thanks for the reality check.
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Voices from the past
 
Richard Vagner
Ranch Hand
Posts: 108
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Bert,

I just bought the book two weeks ago and did not realize it is *old*. I thought I got a good deal .

I checked the errata and it only changes the order of the threads. Since Kathy has suggested the code would be completely revised in the future printing, I am wondering if the new printing has more revisions than simply changing the order of the threads?
[ December 28, 2004: Message edited by: Richard Vagner ]
 
I agree. Here's the link: http://aspose.com/file-tools
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic