从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
可以正常工作。put
和add
是否打算以不同的方式使用? 最佳答案
真的很简单:
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();
}
}