It depends on the implementation. If there are separate queues for different products then each queue must be protected with a separate lock object (this lock object may the queue itself).
Also it depends if you are writing the implementation for the queue then you may decide to have the Lock object as a private variable. On addition you may check if the queue is full you may opt to have wait
on the private lock variable. Once any object is consumed, you can invoke notifyall
(or notify
, though notifyall
is preferable) on the private lock object. Similar way you can have wait
and notify
logic if consumers invoke the method to fetch an element from the queue when it is empty. This way your queue class will be responsible for locking and notifying using the private variable object. As queue has private variable lovk object hence each queue instance will have its own separate Lock object.
Other way is if the queue is general queue, may be its not yo u who is writing the queue, then you will need to protect the code invoking the methods for adding and fetching. In case you have separate queues for different products (x , y , etc.) then you need different Lock objects for each queue. This is needed to prevent deadlocks, it may happen ( if we do not have sepatrate lock objects) a consumerX is waiting for queueX to have a element inserted (as its empty) and another producerY is not getting opportunity to insert in queueY (as its full). Hence you need separate lock objects.
Update
@TheCoder If you have only one producer and consumer both intrested in same type of product then one queue is ok. Now comes the question of Shared object on which both should communicate. It depends upon the implementation, if you wish Queue to take care of it then Queue can have a private field private Object monitor = new Object();
and can have the enqueue
and dequeue
method being synchronized on `monitor'.
In dequeue
method If queue is empty then call monitor.wait()
inside the while
loop until the queue is empty. If queue is not empty then remove the object from queue and call monitor.notifyAll();
In enqueue
method if queue is full call monitor.wait()
in while loop until queue is full. If queue is not full then add an object in queue and call monitor.notifyAll();
If your implementation is such that you wish queue not to take care of syncronization then you should have a shared object on which Producrer
and Consumer
can synchronize before invoking enqueue
and dequeue
on the queue
. This shared object can be the instance of queue
itself. The wait
and notifyAll
will need to be invoked inside the synchronized block on the shared object.