简体   繁体   中英

while loop in java BlockingQueue implementation

I recently saw the following implementation of enqueue for a BlockingQueue ( source )

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

Why is the while loop necessary, and can the while be replaced by if (this.queue.size() == this.limit)

It seems the method enqueue is synchronized so only 1 thread at a time can be executing in the method body and make the call to wait() . Once the thread is notified, can't it just continue onward without checking the this.queue.size() == this.limit condition again?

The documentation on Object.wait() explains it best:

A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied. In other words, waits should always occur in loops, like this one:

 synchronized (obj) {
     while (<condition does not hold>)
         obj.wait(timeout);
     ... // Perform action appropriate to condition
 }

No. You need the while because there might be multiple threads waiting for the space in the queue to open up, and the notifyAll() calls will wake all of them up.

The wait() method actually releases the synchronisation monitor so that other threads can make progress. If it didn't, then any thread trying to remove stuff from the queue would also get stuck waiting to enter a synchronised block in the get() method (for example).

Only one of the waiting threads will see a partially empty queue.

Actually, none of them might; the threads might have been woken up with notifyAll for some completely unrelated reason.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM