Search code examples
javaconcurrencyblockingqueue

Java BlockingQueue confusion


I am currently reading about Java BlockingQueue and this example is given on many websites for a simple implementation of the BlockingQueue. The code is simple but I am a bit confused. For example lets say we fill up the queue, then we try to enqueue 3 more times. This will make the 3 threads wait. Then when we call dequeue, the code in the dequeue method will enter the second if statement and it will notify all threads. Won't this mean that the 3 threads waiting will all add nodes to the queue? That means we will have 2 more nodes than the limit? I am pretty sure I misunderstood something here so I could use some small explanation.

public class BlockingQueue {

  private List queue = new LinkedList();
  private int  limit = 10;

  public BlockingQueue(int limit){
    this.limit = limit;
  }


  public synchronized void enqueue(Object item)
  throws InterruptedException  {
    while(this.queue.size() == this.limit) {
      wait();
    }
    this.queue.add(item);
    if(this.queue.size() == 1) {
      notifyAll();
    }
  }


  public synchronized Object dequeue()
  throws InterruptedException{
    while(this.queue.size() == 0){
      wait();
    }
    if(this.queue.size() == this.limit){
      notifyAll();
    }

    return this.queue.remove(0);
  }

}

Solution

  • No, only one will add a node. Notice that your wait-call in enqueue is inside a loop:

        while(this.queue.size() == this.limit) {
          wait();
        }
    

    All three threads are notified but only one thread can be in the synchronized-block. The first thread to enter the block adds a node, so the queue is full again. The other both threads enter the block (one after another) but see the queue being full again, which will put them right into waiting state again as that's the loop-condition.

    You can imagine a wait to be an exit and entrace point of a synchronized-block. When a thread enters wait, then the corresponding lock is released. A thread that has been waiting in a wait and is notified, is trying to acquire the corresponding lock for the critical section again and blocks if it is currently in use. So only one of the notified three threads can enter at a time.