Java Reference
In-Depth Information
The major difference between calling sleep() and calling wait() is that wait() releases any objects
on which the current thread has a lock, whereas sleep() does not. It is essential that wait() should
work this way, otherwise there would be no way for another thread to change things so that the
condition required by the current thread is met.
Thus the typical use of wait() is:
synchronized(anObject) {
while(condition-not-met)
anObject.wait();
// Condition is met so continue...
}
Here the thread will suspend operation when the wait() method is called until some other thread
synchronized on the same object calls notify() (or more typically notifyAll() ). This allows the
while loop to continue and check the condition again. Of course, it may still not be met, in which case
the wait() method will be called again so another thread can operate on anObject . You can see
from this that wait() is not just for getting access to an object. It is intended to allow other threads
access until some condition has been met. You could even arrange that a thread would not continue
until a given number of other threads had called notify() on the object to ensure that a minimum
number of operations had been carried out.
It is generally better to use notifyAll() rather than notify() when you have more than two
threads synchronized on an object. If you call notify() when there are two or more other threads
suspended having called wait() , only one of the threads will be started, but you have no control over
which it is. This opens the possibility that the thread that is started calls wait() again because the
condition it requires is not fulfilled. This will leave all the threads waiting for each other, with no
possibility of continuing.
Although the action of each of these methods is quite simple, applying them can become very complex.
You have the potential for multiple threads to be interacting through several objects with
synchronized methods and code blocks. We'll just explore the basics by seeing how we can use
wait() and notifyAll() to get rid of a couple of the while loops we had in the last example.
Using wait() and notifyAll() in the Bank Program
In the for loop in main() that generates the transactions and passes them to the Clerk objects, we
have two while loops that call the isBusy() method for a Clerk object. These were needed so that
we didn't pass a transaction to a clerk while the clerk was still busy. By altering the Clerk class, so that
it can use wait() and notifyAll() , we can eliminate the need for these.
Try It Out - Slimming Down the Transactions Loop
We want to make the doTransaction() method in the Clerk class conscious of the state of the
inTray for the current object. If it is not null , we want the method to wait until it becomes so. To use
wait() the block or method must be synchronized on an object - in this case the Clerk object since
inTray is what we are interested in. We can do this by making the method synchronized:
public class Clerk implements Runnable {
private Bank theBank; // The employer - an electronic marvel
Search WWH ::




Custom Search