If a thread executing a synchronized method determines that it cannot pro-
ceed, then it may put itself into a waiting state by calling method wait . This releases
the thread's lock on the shared object and allows other threads to obtain the lock.
A call to wait may lead to an InterruptedException , which must either be caught or
declared to be thrown by the containing ( synchronized ) method.
When a synchronized method reaches completion, a call may be made to
notify , which will 'wake up' a thread that is in the waiting state. Since there is no
way of specifying which thread is to be woken, this is only really appropriate if
there is only one waiting thread. If all threads waiting for a lock on a given object
are to be woken, then we use notifyAll . However, there is still no way of determining
which thread gets control of the object. The JVM will make this decision.
Methods wait , notify and notifyAll may only be called when the current thread
has a lock on the object (i.e., from within a synchronized method or from
within a method that has been called by a synchronized method). If any of these
methods is called from elsewhere, an IllegalMonitorStateException is thrown.
This example is the classical producer-consumer problem, in which a producer is
generating instances of some resource (cars on a production line, chocolate bars on
a conveyor belt, wooden chairs in a carpenter's workshop or whatever) and a con-
sumer is removing instances of the resource. Though this is largely a theoretical
example, rather than a practical example of a service that might be provided by a
server program, it could be modifi ed to involve a server providing some network
resource, such as a printing facility (though the server would probably be working
with a fi xed 'pool' of printers, rather than creating new ones).
The resource will be modelled by a Resource class, while the producer and
consumer will be modelled by a Producer class and a ConsumerClient class respec-
tively. The Producer class will be a thread class, extending class Thread . The server
program, ResourceServer , will create a Resource object and then a Producer
thread, passing the constructor for this thread a reference to the Resource object.
The server will then start the thread running and begin accepting connections from
ConsumerClient s. As each client makes connection, the server will create an
instance of ClientThread (another Thread class), which will be responsible for
handling all subsequent dialogue with the client. The code for ResourceServer is
public class ResourceServer
private static ServerSocket serverSocket;
private static fi nal int PORT = 1234;
public static void main(String args)