Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Cloud/Virtualization forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Threads

 
Reza Kashef
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi all
I�m preparing for the Programmer Exam, and have been reading the good book:
Sun Certified Programmer & Developer for Java2 STUDY GUIDE by Kathy Sierra and Bert Bates.
Today I started on chapter 9 (Threads), and encountered a example I don�t really get.
The example is on page 529, and covers the wait() and notify() methods.

This code compiles and runs just fine, but in my opinion there is a big flaw. In the beginning of the chapter you can read over and over again that thread stuff is not guaranteed.
So how come that the authors assume the thread behaviour in the preceding example?
The example relays on the fact that the first thread (main method in class ThreadA) continues execution and reach the synchronized(b){ (and obtaining the lock on b) BEFORE the synchronized(this){ (in class ThreadB) runs.
For if b runs first and reaches the synchronized(this){ then it gets the lock on itself, thus the main thread will block for the synchronized(b){, and when it gets the lock (when b has ended) then it calls the b.wait(), but will never be notified because b has already run the notify();
Please confirm my statement!
I hope you understand what I mean!? And excuse my bad English, for it�s not my native language.
Merry Christmas and Happy New Year!!!


RK
 
Vad Fogel
Ranch Hand
Posts: 504
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Reza, first of all, welcome to the JavaRanch!
Second of all, it seems like you're right in your observations. Both threads have the same priority of 5, and even though in 999 out of 1000 cases the main thread will try to complete first, there's still a chance that thread b will be chosen to run first, so the main will block on waiting and never complete. I tried to set priority of 7 and up to b before it calls start(), and here we go. To make sure that the "right" thread runs first, one can use Thread.sleep(). That'd be much closer to a guarantee of any kind than relying on the pure scheduler implementation.
 
Reza Kashef
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Vad Fogel
 
Don Wood
Ranch Hand
Posts: 65
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Good catch, Reza! And welcome to Java Ranch.
Using sleep, yield and thread priorities to alter execution is rather unpredictable. Also, sleep will slow down your application. You can start these threads so they will always run in a correct and predictable manner by moving the start inside the synchronized block and before the call to b.wait(). I modified the code below:

Now if thread b does start right away, it will wait at the start of its synchronized block until the main thread releases the lock in the b.wait()call.
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Reza. Welcome to the JavaRanch.
This example reminds me of the producer-consumer problem. The consumer first checks if there is anything to consume. If there is nothing to consume, the consumer waits.

This way, thread-A will not wait forever if thread-B acquires the lock first.
[ December 22, 2003: Message edited by: Marlene Miller ]
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The synchronized keyword is a way to keep threads from interfering with each other.
The wait and notify keywords are a way for threads to communicate with each other. One thread does not proceed until some condition is satisfied. Another thread notifies the first thread when the condition is satisfied.
The first thread must test the condition before waiting. That is part of the communication protocol.
 
Don Wood
Ranch Hand
Posts: 65
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The point is that when a thread is started you are not guaranteed which thread will run. Either the starting thread or the newly started thread can run. As Reza pointed out, the original question was incorrectly coded.
What I described was a specific correction that would make the original code run as intended. Marlene presents the more general and elegant solution described in the producer-consumer model. And it is always a good idea to use these tried and proven methods.
[ December 22, 2003: Message edited by: Don Wood ]
[ December 22, 2003: Message edited by: Don Wood ]
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The general pattern for using wait and notify is this

However, when studying for the exam, we see all kinds of atypical code.
 
Reza Kashef
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I feel indeed welcomed here because of all the nice people and the quick replays, thanks.
And ones again Merry Christmas and Happy New Year.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic