来自 ArrayBlockingQueue
的 Javadoc ArrayBlockingQueue :
add
public boolean add(E e)
Inserts the specified element at the tail of this queue if it is possible to do so immediately without exceeding the queue's capacity, returning true upon success and throwing an IllegalStateException if this queue is full.
我总是这样解释这个语句(if is possible to do so immediately
部分)如下:
If the queue has free capacity, then the insert will succeed. If there is no empty space then it will not succeed.
但是这里我的理解是错误的。
在一个简单的例子中,我决定使用一个 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
不会抛出异常,但不会将元素添加到队列中。
只是一个想法:也许由于消费者在队列中“等待”,如果由于某些内部管理无法添加元素,则不会添加它并且不会抛出异常。可能是这种情况。
否则我无法理解为什么没有异常并且使用 put
代码可以工作。
put
和 add
的用法不同吗?
最佳答案
其实很简单:
我认为文档在上面已经很清楚了。如果您不同意并希望获得第二意见,您可以检查 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();
}
}
关于java - ArrayBlockingQueue 和添加 vs 放置 vs 容量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7706666/