ArrayBlockingQueue и add vs put vs capacity

Из Javadoc от ArrayBlockingQueue ArrayBlockingQueue:

add

public boolean add(E e)

Вставляет указанный элемент в хвост этой очереди, если возможно 
сделать это немедленно без превышения емкости очереди, возвращая true 
при успехе и выбрасывает IllegalStateException, если очередь переполнена.

Я всегда интерпретировал это утверждение (часть если это возможно сделать немедленно) следующим образом:

Если в очереди есть свободное место, то вставка будет успешной. Если свободного места нет, то вставка не будет успешной.

Но здесь мое понимание было неверным.

В простом случае, когда я решил использовать ArrayBlockingQueue, например, для 20 элементов (маленькая очередь) и один поток делает:

queue.take()

другой поток не добавил элемент в очередь через метод add, несмотря на то, что очередь была почти пуста.

Я проверил это также через отладку.

Как только я заменил вызов queue.add(element) на queue.put(element), элемент действительно был добавлен в очередь.

Так что же такого разного в этих методах?

По какой еще причине (кроме емкости) добавление не могло произойти?


UPDATE:

public class ConnectionListener implements Observer {

  public static BlockingQueue queueConnections = new   ArrayBlockingQueue(10);

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

}  

ConnectionObject - это просто держатель для строковых значений.

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, исключение не возникает, но элемент не добавляется в очередь.

Просто мысль: возможно, поскольку потребитель "ждет" очереди, если по каким-то внутренним причинам элемент не может быть добавлен, он не будет добавлен, и исключение не будет выброшено.Может ли это быть так?

Иначе я не могу понять, почему нет исключения и с put код работает.

Неужели put и add должны использоваться по-разному?

9
задан Cratylus 9 October 2011 в 21:47
поделиться