【问题标题】:Blocking Queue - Why is there no notify()阻塞队列 - 为什么没有 notify()
【发布时间】:2015-02-01 18:25:59
【问题描述】:

我在网上通过这个边界队列代码试图理解它

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();
    }
    if(this.queue.size() == 0) {
      notifyAll();
    }
    this.queue.add(item);
  }


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

    return this.queue.remove(0);
  }

}

我的理解是这样的:

  1. 如果队列中没有更多项目,则无法出队,因此我们调用 wait()
  2. 如果队列中有最大数量的项目,则无法入队,因此我们调用 wait()
  3. 如果队列中有一些空间(和一些元素),我们可以调用入队和出队
  4. 我们还 notifyAll() 以便所有生产者和消费者醒来

但是我们调用 wait() 的请求会发生什么。他们是否只在 notifyAll() 调用中得到通知?为什么他们在队列中有空间时没有收到通知?

【问题讨论】:

  • 只是这里只能看到notifyAll(),没有notify。他们如何得到通知?
  • 你认为notifyAll 是做什么的?
  • notifyAll() 仅在没有更多元素时在入队中调用,在有最大元素时在出队中调用。我的问题正是如此。为什么要等待这些限制?为什么不尽快通知?
  • 如果队列达到大小限制,notifyAll 也会在 dequeue 上调用。

标签: java multithreading client-server producer-consumer


【解决方案1】:

您只需要在添加到空队列时通知,因为出队只在空队列上等待。

同样,您只需要在从满队列中出队时通知,因为入队者只在满队列中等待。

【讨论】:

  • 哦,我想现在开始有意义了。谢谢
【解决方案2】:

理解代码需要注意的两个细节:

  1. 线程在唤醒之前也必须获得锁,这就是为什么两个notifyAll可以放在最后一行以外的地方。
  2. 除了等待,还有排队。当没有线程在等待其条件时,所有线程都在排队获取锁,这就是代码仅在队列满或空时才执行notifyAll 的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-16
    • 2019-10-16
    • 2014-08-11
    • 2011-04-10
    • 2017-07-30
    • 1970-01-01
    • 2010-10-24
    • 1970-01-01
    相关资源
    最近更新 更多