This week's book giveaway is in the OCAJP 8 forum.
We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line!
See this thread for details.
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes doubt in thread: notifyAll() Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login

Win a copy of OCA Java SE 8 Programmer I Study Guide this week in the OCAJP 8 forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "doubt in thread: notifyAll()" Watch "doubt in thread: notifyAll()" New topic

doubt in thread: notifyAll()

Leandro Coutinho
Ranch Hand

Joined: Mar 04, 2009
Posts: 423

the classes below are from K&B Java 2 Certified & Developer:

It always prints Waiting for calculation... three times and sometimes prints Total is: 4950, eg:
Waiting for calculation...
Waiting for calculation...
Waiting for calculation...
Total is: 4950
Total is: 4950

The real problem is that the program don't finishe, you need to abort it :/
What is wrong with this code?
Devaka Cooray
ExamLab Creator

Joined: Jul 29, 2008
Posts: 3713

Hello Leandro,

Look at the run() method of the Reader class carefully. There, the statement c.wait() is used to wait the current thread for the given Calculator object. The thread can continue, only if a notification (i.e. notifyAll() ) is send on that Calculator instance. Otherwise the thread should continue waiting, so the program could not exit unless that thread is a daemon thread.

Now look at the main method:

There are total of 4 threads started by the main method, as 1 Calculator thread and 3 Reader threads. But we couldn't say that which thread will start the execution as first, because it is a job of the thread scheduler. In other words, thread starting order is unpredictable here.

If the Calculator thread is started as first, the run() method of the Calculator thread will be completed, before running any other threads. In this case, all of the other 3 threads can execute the method, only after the completion of the Calculator thread. After the completion of the Calculator thread, the other three Reader threads can execute the statement System.out.println("Waiting for calculation..."); But when no one of these threads can proceed the execution after the statement, c.wait(). Think about it, now the execution of the Calculator thread is already finished, hence there are no chance to execute the notifyAll(); statement again. Therefore these three threads have to wait and wait on the c.wait() statement. The program could not terminate on this case.

But that is a one possibility only. What if one or many Reader threads have started there execution before the Calculator thread? In that case, there is a chance to pass the wait() statement, because the notifyAll() statement can be executed *after* the wait() statement. More specifically, if the Calculator thread is started the execution after *all* of the other three Reader threads, the notification could be sent for all three waiting threads successfully. Therefore, all of these four threads can end their execution, hence the program will be terminated successfully.



Author of ExamLab ExamLab - a free SCJP / OCPJP exam simulator
What would SCJP exam questions look like? -- Home -- Twitter -- How to Ask a Question
Leandro Coutinho
Ranch Hand

Joined: Mar 04, 2009
Posts: 423
Thanks Devaka!!!
Ulrich Vormbrock
Ranch Hand

Joined: Apr 15, 2010
Posts: 73
Thanks - Devaka - for your precise explanation! This helped me a lot because (cramming for SCJP 6), I came across the same problem, trying to figure out how (and in which order) the above mentioned threads are interacting with each other.

Apparently, these threads are likely to start in an inappropriate order, due to the fact that the thread scheduler can be a bit lunatic and unpredictable concerning the order he starts his threads from the thread pool (it's right not to call it a "thread queue" ...)

I've tried to solve this problem by introducing a static variable (line 2) in the Reader class. When a new Reader instance is created and started by run(), the variable numReaders is incremented by 1 ... until the number of 3 is reached. On the other hand, the monitor (Calculator) can perform its calculation (and, of cause, notify all waiting threads) only when numReaders is exactly three - see line 41 - in other words: when all "Reader threads" have been started and are now waiting for notification - notifyAll() - originating from the Calculator, being ready to receive and to print out the result "total".

I'm not sure if my approach is good practice - if there is another or better solution, please give me a hint or a suggestion how to solve this problem more accurately!
Same thing for my explanation, because trying to get a deeper understanding of threads, I'm actually toughing me up concerning this issue.

Thanks in advance!

Below, please find my "enhanced" version of the "Reader and Calculator class", K&B SCJP6, chapter 9, page 752 - 753.

The output (on my machine) is constantly:

Waiting for calculation ... Thread "Reader": 1
Waiting for calculation ... Thread "Reader": 2
Waiting for calculation ... Thread "Reader": 3
Total is: 4950
Total is: 4950
Total is: 4950


SCJP 6 (88%), SCWCD (89%)
bhanu chowdary
Ranch Hand

Joined: Mar 09, 2010
Posts: 256
Nice explanation Devaka
I agree. Here's the link:
subject: doubt in thread: notifyAll()
It's not a secret anymore!