Из 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
должны использоваться по-разному?