[英]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.