首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java BlockingQueue混淆

Java BlockingQueue混淆
EN

Stack Overflow用户
提问于 2020-08-07 09:56:09
回答 2查看 137关注 0票数 1

我目前正在阅读关于Java的文章,在许多网站上都给出了这个示例,以实现BlockingQueue的简单实现。代码很简单,但我有点困惑。例如,假设我们填充了队列,然后再尝试加入3次队列。这将使3个线程等待。然后,当我们调用dequeue时,dequeue方法中的代码将输入第二个if语句,并通知所有线程。这不意味着等待的3个线程都会向队列中添加节点吗?这意味着我们将多出两个节点的限制?我很肯定我在这里误解了一些东西,所以我需要一些小小的解释。

代码语言:javascript
复制
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);
  }

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-08-07 10:04:33

不,只有一个会添加一个节点。注意,wait-call in enqueue在一个循环中:

代码语言:javascript
复制
    while(this.queue.size() == this.limit) {
      wait();
    }

所有三个线程都会被通知,但是只有一个线程可以在synchronized-block中。进入块的第一个线程添加了一个节点,因此队列又满了。另两个线程(一个接一个地)进入块,但是看到队列又满了,这将使它们再次进入等待状态,因为这是循环条件。

您可以将wait想象为synchronized-block的出口和内聚点。当线程进入wait时,相应的锁就会被释放。在wait中等待并收到通知的线程正试图再次获取关键部分的相应锁,如果它目前正在使用,则会阻塞。因此,通知的三个线程中只有一个可以一次进入。

票数 1
EN

Stack Overflow用户

发布于 2020-08-07 10:05:45

请注意,来自wait().enqueue()在循环中。任何唤醒线程都将重新检查允许添加元素,而且由于一次只有单个线程可以执行同步方法,所以没有问题--一个线程很幸运地插入了一个元素,其他线程在失败的重新检查之后继续等待。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63299412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档