ArrayBlockingQueue ArrayBlockingQueue的Javadoc中:



我总是将此语句(if it is possible to do so immediattely部分)解释如下:



但是我的理解是错误的。

在一个简单的情况下,我决定使用ArrayBlockingQueue例如20个元素(小队列),并有一个线程在做:
queue.take()
尽管队列几乎为空,但另一个线程没有通过add方法将元素添加到队列中。

我也通过调试验证了它。

一旦我将queue.add(element)的调用替换为queue.put(element),该元素的确已添加到队列中。

那么这些方法有什么不同呢?

出于其他什么原因(除了容量),添加不会发生?

更新:

public class ConnectionListener implements Observer {

  public static BlockingQueue<ConnectionObject> queueConnections = new   ArrayBlockingQueue<ConnectionObject>(10);

  @Override
  public void update(Observable arg0, Object arg1) {
      ConnectionObject con = ((ConnectionObject)arg1);
      queueConnections.add(con);
  }

}
ConnectionObject只是String值的持有者。
public class ConnectionObject {
  private String user;
  private String ip;
   //etc
}

和消费者:
public class ConnectionTreeUpdater extends Thread {
  @Override
  public void run() {
    while(true){
    try {
    final ConnectionObject con = ConnectionListener.queueConnections.take();

如果我使用add,则不会引发任何异常,但不会将元素添加到队列中。

只是想一想:也许由于消费者正在队列中“等待”,如果对于某些内部管理而言,无法添加该元素,则不会添加该元素,并且不会引发任何异常。

否则我不明白为什么没有异常(exception),并且使用put可以正常工作。
putadd是否打算以不同的方式使用?

最佳答案

真的很简单:

  • 如果队列未满,则这两种方法都会成功;否则,两种方法都会成功。
  • (如果队列已满), add() 失败,但有一个异常(exception),而 put() 阻塞。

  • 我认为上面的文档非常清楚。如果您不同意并希望第二意见,则可以检查ArrayBlockingQueue的源代码:
    public boolean add(E e) {
        if (offer(e))
            return true;
        else
            throw new IllegalStateException("Queue full");
    }
    
    public boolean offer(E e) {
        if (e == null) throw new NullPointerException();
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            if (count == items.length)
                return false;
            else {
                insert(e);
                return true;
            }
        } finally {
            lock.unlock();
        }
    }
    
    public void put(E e) throws InterruptedException {
        if (e == null) throw new NullPointerException();
        final E[] items = this.items;
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            try {
                while (count == items.length)
                    notFull.await();
            } catch (InterruptedException ie) {
                notFull.signal(); // propagate to non-interrupted thread
                throw ie;
            }
            insert(e);
        } finally {
            lock.unlock();
        }
    }
    

    09-25 22:13
    查看更多