阻止队列 - 为什么没有notify()

时间:2015-02-01 18:25:59

标签: java multithreading client-server producer-consumer

我正在线上尝试理解这个边界队列代码

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. 如果队列中有一些空格(和一些元素),我们可以调用enqueue和dequeue
  4. 我们也通知所有()所有生产者和消费者醒来
  5. 但是我们调用wait()的请求会发生什么。他们只会收到notifyAll()电话的通知吗?为什么一旦队列中有空间就不会得到通知?

2 个答案:

答案 0 :(得分:3)

添加到空队列时只需要通知,因为dequeuers只等待空队列。

类似地,您只需要在从完整队列出队时通知,因为入队者只在等待完整队列。

答案 1 :(得分:0)

要了解代码,请注意两个细节:

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