java - java BlockingQueue 实现中的 while 循环

标签 java blockingqueue

我最近看到了以下 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);
}

为什么需要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
 }

关于java - java BlockingQueue 实现中的 while 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9839388/

相关文章:

java - Java 中 BlockingQueue 上的并发 put 调用

Java:线程生产者消费者等待数据产生的最有效方法是什么

java - 将选定的行插入mysql

Java连续GC,ParOldGen耗尽

java - 如何以多线程方式调用不同类的相同方法

java - 阻塞队列与信号量

Java异步方法调用/后台处理

java - 线程无法捕获 InterruptionException

java - 如何以任意顺序使用字符串和整数组合作为输入?

java - 为什么十六进制表示 89 在 Java 中使用 toString 后不能正确打印为 ‰?