Reputation: 79
I am trying to understand Java's synchronized keyword, wait(), and notify() by implementing a blocking queue class. One of the blocking queue implementation is described by this article. However I wonder if it is possible to use two objects serving as lock to implement blocking queue? Is the below code correct?
public class BlockingQueue {
private List<Object> queue = new LinkedList<Object>();
private int limit;
private Object slots = new Object();
private Object objs = new Object();
public BlockingQueue(int limit) {
this.limit = limit;
}
private synchronized void enqueue(Object o)
throws InterruptedException {
if (queue.size() == limit)
slots.wait();
objs.notify();
queue.add(o);
}
private synchronized Object dequeue()
throws InterruptedException {
if (queue.size() == 0)
objs.wait();
slots.notify();
return queue.remove(0);
}
}
Upvotes: 0
Views: 636
Reputation: 2121
First of all, you cannot wait or notify on an object that you didn't synchronized on. Here you would use this.wait() and this.notifyAll.
Second, you should never wait() just once without rechecking your condition. Whatever you put in the 'if' should be in a while loop; that is because you could get notified by mistake without the condition having changed, especially since you are using the monitor on the instance which anyone outside can synchronize and notify on. You should rather use a synchronized(privatelockobject) {}.
This leads to your question, can you synchronize 2 + objects... Yes, by nesting synchronized blocks, but that will lead to hanging code, since the wait() call only free the one monitor you waited on, not the outer monitor. This is therefore pointless.
If you were trying to avoid notifying both readers and writers waiting on the queue, this is an honorable thought, but you cannot do it with synchronized. The example cited is doing it with a single monitor, and this is also why it must use notifyAll() instead of notify(), because you want to make sure to wake the proper thread waiting. Normally you have to use ReentrantLock with 2 distinct conditions (not empty, and not full).
Upvotes: 1