Cra*_*lus 9 java queue concurrency multithreading data-structures
来自ArrayBlockingQueue ArrayBlockingQueue的 Javadoc :
加
public boolean add(E e)
Run Code Online (Sandbox Code Playgroud)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 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);
}
}
Run Code Online (Sandbox Code Playgroud)
ConnectionObject 只是String值的持有者.
public class ConnectionObject {
private String user;
private String ip;
//etc
}
Run Code Online (Sandbox Code Playgroud)
和消费者:
public class ConnectionTreeUpdater extends Thread {
@Override
public void run() {
while(true){
try {
final ConnectionObject con = ConnectionListener.queueConnections.take();
Run Code Online (Sandbox Code Playgroud)
如果我使用add没有抛出异常,但元素不会被添加到队列中.
只是一个想法:也许是因为消费者在队列上"等待",如果对于某些内部管理,该元素无法添加,则不会添加,也不会抛出任何异常.可能就是这种情况.
否则我无法理解为什么没有异常并且put代码有效.
是put和add意味着要使用不同?
NPE*_*NPE 17
这很简单:
我认为上面的文档很清楚.如果您不同意,并希望获得第二意见,您可以查看源代码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();
}
}
Run Code Online (Sandbox Code Playgroud)