繁体   English   中英

Java BlockingQueue实现中的while循环

[英]while loop in java BlockingQueue implementation

我最近看到了BlockingQueue的入队的以下实现(

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);
}

为什么while循环是必需的, while可以被if (this.queue.size() == this.limit)取代

似乎方法队列是同步的,因此一次只能在该方法主体中执行1个线程,并调用wait() 一旦通知了线程,就可以不继续检查this.queue.size() == this.limit条件而继续前进吗?

关于Object.wait()的文档对此做了最好的解释:

线程也可以唤醒,而不会被通知,中断或超时,即所谓的虚假唤醒。 尽管在实践中这种情况很少发生,但是应用程序必须通过测试应该导致线程唤醒的条件来防范它,并在条件不满足时继续等待。 换句话说,等待应该总是像这样循环执行:

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

不需要。您需要一段时间,因为可能有多个线程正在等待打开队列中的空间,并且notifyAll()调用将唤醒所有线程。

实际上,wait()方法释放了同步监视器,以便其他线程可以取得进展。 如果没有,那么任何试图从队列中删除内容的线程也将被阻塞,等待在get()方法中输入同步块(例如)。

只有一个等待线程将看到部分为空的队列。

实际上,它们都不可能。 线程可能由于某些完全不相关的原因被notifyAll唤醒。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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