ArrayBlockingQueue 以及添加、放置和容量
来自 ArrayBlockingQueue
ArrayBlockingQueue:
添加
公共布尔添加(E e)
如果可能,将指定元素插入到此队列的尾部 立即执行此操作而不超出队列的容量,返回 true 成功后,如果队列已满,则抛出 IllegalStateException。
我总是解释这个语句(如果可以立即这样做
部分)如下:
如果队列有空闲容量,则插入将会成功。如果没有空白,则不会成功。
但我的理解在这里是错误的。
在一个简单的情况下,我决定使用 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
只是字符串值的持有者。
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
的用法是否不同?
From Javadoc of ArrayBlockingQueue
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.
I always interpretted this statement (the part if it is possible to do so immediattely
) as follows:
If the queue has free capacity, then the insert will succeed. If there is no empty space then it will not succeed.
But my understanding was wrong here.
In a simple case that I decided to use an ArrayBlockingQueue
for e.g. 20 elements (small queue) and having one thread doing:
queue.take()
the other thread did not add an element to the queue via the add
method despite the queue was almost empty.
I verified it also via debugging.
Once I replaced the call of queue.add(element)
to queue.put(element)
the element was indeed added to the queue.
So what is so different in these to methods?
For what other reason (besides capacity) could the addition not happen?
UPDATE:
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
is just a holder for String values.
public class ConnectionObject {
private String user;
private String ip;
//etc
}
And the consumer:
public class ConnectionTreeUpdater extends Thread {
@Override
public void run() {
while(true){
try {
final ConnectionObject con = ConnectionListener.queueConnections.take();
If I use add
no exception is thrown but element does not get added to the queue.
Just a thought: perhaps since the consumer is "waiting" on the queue, if for some internal housekeeping the element can not be added it will not be added and no exception is thrown.Could that be the case.
Otherwise I can not understand why there is no exception and with put
the code works.
Are put
and add
meant to be used differently?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
其实很简单:
添加()
因异常而失败,而put()
块。我认为上述文档已经非常清楚了。如果您不同意并希望获得第二意见,您可以检查 ArrayBlockingQueue 的源代码:
It's quite simple really:
add()
fails with an exception whereasput()
blocks.I think the documentation is pretty clear on the above. If you don't agree, and would like a second opinion, you could examine the source code for
ArrayBlockingQueue
:调试问题更重要的部分之一是编写测试用例以确保您认为正在发生的事情确实发生了。这要么证明了你的理论,要么反驳了你的理论。
下面的测试用例显示您正在使用的方法的行为与文档(您引用的)完全相同:
One of the more important parts of debugging a problem is writing a test case to make sure what you think is happening is indeed happening. This either proves or disproves your theory.
The test case below shows that the methods you are using behave exactly as the documentation (which you quote) states: